在WPF这种应用程序中,会有两大类未处理异常:一类是在UI线程抛出来的,例如点击了用户界面上面的某个控件,然后执行某个代码的时候,遇到了异常;另一类是非UI线程跑出来的,例如在一个多线程的程序里面,工作线程的代码遇到了异常,使用DispatcherUnhandledException事件来处理。
对于非UI线程抛出的未处理异常,我们需要监控另外一个事件UnhandledException来处理。但是事件中没有和前面那个事件一样的e.Handled参数,所以即使可以捕捉到非UI线程的异常,而且也可以进行相应的处理,但是应用程序还是会退出,也就是说这个异常还是被当作是未处理异常继续汇报给Runtime。
using System;
using System.Windows;
namespace WpfApplicationExceptionSample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("我们很抱歉,当前应用程序遇到一些问题,该操作已经终止,请进行重试,如果问题继续存在,请联系管理员.", "意外的操作", MessageBoxButton.OK, MessageBoxImage.Information);//这里通常需要给用户一些较为友好的提示,并且后续可能的操作
e.Handled = true;//使用这一行代码告诉运行时,该异常被处理了,不再作为UnhandledException抛出了。
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show("我们很抱歉,当前应用程序遇到一些问题,该操作已经终止,请进行重试,如果问题继续存在,请联系管理员.", "意外的操作", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
}
WPF中对于非UI线程在4.0之后的异常好像默认是抛出的,不做处理的,为了优化用户体验,可以开启处理异常。
配置方式如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>