在App中设置Nlog日志记录,并实现全局异常处理。
public partial class App{
protected override async void OnInitialized()
{
_logger = Container.Resolve<ILogger<App>>();
_logger?.LogInformation("应用启动...");
RegisterGlobalExceptionHandling();
base.OnInitialized();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 项目中注册的服务
// 注册 ILoggerFactory 并配置 NLog
containerRegistry.RegisterSingleton<ILoggerFactory>(() =>
{
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.ClearProviders(); // 清除默认的日志提供程序
builder.AddNLog(); // 添加 NLog 支持
builder.SetMinimumLevel(LogLevel.Debug); // 设置最小日志级别
});
// 加载 NLog 配置(禁用 ASP.NET Core 扩展扫描)
LogManager.Setup()
.SetupExtensions(ext => { }) // 禁用自动加载扩展
.LoadConfigurationFromFile("nlog.config");
return loggerFactory;
});
//var allTargets = LogManager.Configuration.AllTargets;
//foreach (var target in allTargets)
//{
// Debug.WriteLine(target.GetType().Name + "********************************");
//}
// 注册泛型 ILogger<T>,便于依赖注入
containerRegistry.Register(typeof(ILogger<>), typeof(Logger<>));
}
private void RegisterGlobalExceptionHandling()
{
DispatcherUnhandledException += OnDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
}
/// <summary>
/// UI线程异常处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
var exception = e.Exception;
_logger?.LogError(exception, $"UI线程异常:{exception.Message}");
e.Handled = true;
}
/// <summary>
/// 非UI线程异常处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
_logger?.LogError(exception, $"非UI线程异常,IsTerminating: {e.IsTerminating},Message: {exception.Message}");
}
/// <summary>
/// 未观察到的任务异常处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
_logger?.LogError(e.Exception, "未观察到的任务异常");
e.SetObserved();
}
}
}
nlog.config文件内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Error"
internalLogFile="logs/internal-nlog.txt"
internalLogMaxFileSize="5242880">
<targets>
<!-- 优化后的文件Target -->
<target name="file" xsi:type="File"
fileName="logs/${shortdate}.log"
layout="${longdate}|${level:uppercase=true}|${logger:shortName=true}|${message:withException=true}${newline}${exception:format=Message,StackTrace:separator= : }${newline}" />
<!-- 控制台输出 -->
<target name="console" xsi:type="Console"
layout="${time} | ${level:uppercase=true:padding=5} | ${logger:shortName=true:padding=20} | ${message:withException=true}" />
<!-- 可选:添加一个调试用的简洁格式 -->
<target name="debugFile" xsi:type="File"
fileName="logs/debug-${shortdate}.log"
layout="${longdate} | ${level:uppercase=true} | ${logger:shortName=true} | ${message}${onexception:${newline}EXCEPTION: ${exception:format=Message}}" />
</targets>
<rules>
<!-- 默认规则 -->
<logger name="*" minlevel="Debug" writeTo="file,console" />
<!-- 减少Microsoft.*的日志噪音 -->
<logger name="Microsoft.*" minlevel="Warn" final="true" />
<logger name="System.*" minlevel="Warn" final="true" />
</rules>
</nlog>
// 这些都是UI线程操作
private void Button_Click(object sender, RoutedEventArgs e)
{
// 以下操作都在UI线程执行
textBox.Text = "Hello"; // 更新UI控件
this.Title = "新标题"; // 修改窗口属性
throw new Exception("UI线程异常"); // 这里抛出的是UI线程异常
}
// 典型的UI线程异常场景:
private void UpdateUI()
{
// 直接操作UI控件 - 在UI线程执行
button.Content = "点击我";
progressBar.Value = 50;
// 如果这里抛出异常,就是UI线程异常
var invalidData = someArray[999]; // 可能越界
}
// 这些是非UI线程操作
private void StartBackgroundWork()
// Thread 创建新线程
var thread = new Thread(() =>
{
ReadFileContent(); // 文件操作
throw new Exception("线程异常");
});
thread.Start();
}
// 定时器也在非UI线程
private void SetupTimer()
{
var timer = new Timer(_ =>
{
// 这里是非UI线程
CheckSystemStatus();
throw new Exception("定时器异常");
}, null, 1000, 1000);
}
未观察到的任务异常:UnobservedTaskException
private void StartTask()
{
Task.Run(() => throw new Exception("任务异常"));
// 没有 await,没有检查 Result,异常被"忽略"
// → TaskScheduler.UnobservedTaskException
}