WPF 程序未处理异常 的捕获
static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
{
Util.Log(e.ExceptionObject.ToString());//写日志
}
void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
System.Windows.MessageBox.Show(e.Exception.Message);
Util.Log(e.Exception.ToString());//写日志
e.Handled = true;
//throw e.Exception;
}
public MainWindow()
{
InitializeComponent();
//调用此处能够让程序不崩溃
App.Current.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(Current_DispatcherUnhandledException);
//调用此处,只是通知出错的信息,程序仍然会奔溃
//AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);
}
两个函数的区别:
http://www.cnblogs.com/surpasslight/archive/2012/02/10/2345149.html
我首先想到的是应用程序域AppDomain类型的UnhandledExceptionEventHandler,试了试才知道原来AppDomain.UnhandledExceptionEventHandler就是一个通知性质的事件,没有处理异常的功能,自然未处理异常还会是程序崩溃。它的UnhandledExceptionEventArgs中有两个属性:IsTerminating和ExceptionObject,分别代表程序是否在崩溃和引起崩溃的异常对象。
比如这段代码:
staticvoid Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=newUnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
thrownewException("test");
}
staticvoid CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("完蛋了?:"+ e.IsTerminating);
Console.WriteLine("谁干的?:"+ e.ExceptionObject);
}
结果:
程序还是崩溃了……
看来.NET Framework BCL中没有专门处理CLR未处理异常的方法。
看来WPF程序只能使用自己的Dispatcher.UnhandledException事件,这个事件碉堡了,任何当前Dispatcher线程(即UI线程)的未处理异常都可以选择处理或者不处理(通过DispatcherUnhandledExceptionEventArgs.IsHandled属性),选择处理的话未处理异常就不会崩溃整个WPF应用程序了。
比如在按钮点击后抛出一个异常:
privatevoid Button_Click(object sender, RoutedEventArgs e)
{
Dispatcher.UnhandledException +=newDispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
thrownewException("test");
}
void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled =true;
}
结果:
一个消息框出现,关闭后程序继续运行。