- 注册并定义3个全局异常事件处理函数
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//全局错误处理
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;//Thead,处理在非UI线程上未处理的异常,当前域未处理异常
DispatcherUnhandledException += App_DispatcherUnhandledException;//处理在UI线程上未处理的异常
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;//处理在Task上未处理的异常
}
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
// 处理未被观察的异常
// 可以记录日志或执行其他操作
MessageBox.Show("TaskScheduler_UnobservedTaskException出现错误:" + Environment.NewLine + e.Exception.ToString());
// 标记异常已处理,防止应用程序崩溃
e.SetObserved();
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// 处理未经处理的异常
// 请注意,这里的异常是无法恢复的,应用程序可能会退出
MessageBox.Show("CurrentDomain_UnhandledException出现错误:" + Environment.NewLine + e.ExceptionObject.ToString());
}
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// 处理未经处理的异常
// 请注意,这里的异常是无法恢复的,应用程序可能会退出
// 显示错误信息
MessageBox.Show("App_DispatcherUnhandledException出现错误:" + Environment.NewLine + e.Exception.ToString());
// 终止事件传播,防止应用程序崩溃
e.Handled = true;
}
- 触发异常
//触发异常
public ICommand TriggerExceptionCommand
{
get => new DelegateCommand(async() =>
{
触发ui异常,引发App_DispatcherUnhandledException
//int i = 0;
//int a = 20 / i;
不用await引发的是TaskScheduler_UnobservedTaskException出现错误
使用await引发的是引发App_DispatcherUnhandledException出现错误
//await Task.Run(() =>
//{
// //int i = 0;
// //int a = 20 / i;
// App.Current.Dispatcher.Invoke(() =>
// {
// //不用await引发的是TaskScheduler_UnobservedTaskException出现错误
// //使用await引发的是引发App_DispatcherUnhandledException出现错误
// int i = 0;
// int a = 20 / i;
// });
//});
引发的是CurrentDomain_UnhandledException出现错误
//new Thread(() =>
//{
// //int i = 0;
// //int a = 20 / i;
// App.Current.Dispatcher.Invoke(() =>
// {
// //引发的是CurrentDomain_UnhandledException出现错误
// int i = 0;
// int a = 20 / i;
// });
//}).Start();
});
}
在WPF应用程序中实现全局捕获异常可以使用Application.DispatcherUnhandledException事件。此事件会在未处理的异常冒泡到应用程序的顶层时触发。
可以在App.xaml.cs中的OnStartup方法中添加以下代码来订阅该事件并处理全局异常:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//全局错误处理
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;//Thead,处理在非UI线程上未处理的异常,当前域未处理异常
DispatcherUnhandledException += App_DispatcherUnhandledException;//处理在UI线程上未处理的异常
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;//处理在Task上未处理的异常
}
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
// 处理未被观察的异常
// 可以记录日志或执行其他操作
MessageBox.Show("TaskScheduler_UnobservedTaskException出现错误:" + Environment.NewLine + e.Exception.ToString());
// 标记异常已处理,防止应用程序崩溃
e.SetObserved();
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// 处理未经处理的异常
// 请注意,这里的异常是无法恢复的,应用程序可能会退出
MessageBox.Show("CurrentDomain_UnhandledException出现错误:" + Environment.NewLine + e.ExceptionObject.ToString());
}
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// 处理未经处理的异常
// 请注意,这里的异常是无法恢复的,应用程序可能会退出
// 显示错误信息
MessageBox.Show("App_DispatcherUnhandledException出现错误:" + Environment.NewLine + e.Exception.ToString());
// 终止事件传播,防止应用程序崩溃
e.Handled = true;
}
在上述代码中,CurrentDomain.UnhandledException事件用于处理在非UI线程上未处理的异常,而DispatcherUnhandledException事件用于处理在UI线程上未处理的异常。在事件处理程序中,可以添加自定义的异常处理逻辑,比如记录日志、提示用户等。
需要注意的是,DispatcherUnhandledException事件中的e.Handled属性应设置为true,以表示已经处理了异常,阻止应用程序继续抛出异常并崩溃。而CurrentDomain.UnhandledException事件中无法设置Handled属性,应用程序可能会直接退出。
此外,还可以考虑使用其他工具和框架来增强全局异常处理,如在App.xaml.cs中配置TaskScheduler.UnobservedTaskException来处理Task异常,或使用第三方的异常处理库(如Serilog、NLog等)来记录异常日志和提供更丰富的异常处理功能。