WPF全局异常捕获处理

发布时间 2023-04-12 13:58:23作者: Morning=Sunshine

private void RegisterEvents()
{
//Task线程内未捕获异常处理事件
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;//Task异常
//UI线程未捕获异常处理事件(UI主线程)
DispatcherUnhandledException += App_DispatcherUnhandledException;
//非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
//Task线程内未捕获异常处理事件
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
try
{
Exception? exception = e.Exception as Exception;
if (exception != null)
{
this.Logger.Error(exception);
}
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
finally
{
e.SetObserved();
}
}
//非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
var exception = e.ExceptionObject as Exception;
if (exception != null)
{
this.Logger.Error(exception);
}
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
finally
{
//ignore
}
}
//UI线程未捕获异常处理事件(UI主线程)
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
try
{
this.Logger.Error(e.Exception);
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
finally
{
e.Handled = true;
}
}

配置 legacyUnhandledExceptionPolicy

监听 Dispatcher.UnhandledException 事件设置 e.Handled = true 来标记异常已被正确处理,程序不会退出。事件 Appdomain.CurrentDomain.UnhandledException不允许开发者标记 e.Handled = true,但有这个事件中有一个属性 IsTerminating 标记应用程序是否因为这次异常退出。
在 app.config 文件的 <runtime> 节点中添加如下代码:<legacyUnhandledExceptionPolicy enabled="1"/> 加上这个配置之后,Appdomain.CurrentDomain.UnhandledException 事件的 IsTerminating 就变成了 false,程序并不会当前的异常而崩溃退出。