我首先想到的是應用程式定義域AppDomain類型的UnhandledExceptionEventHandler,試了試才知道原來AppDomain.UnhandledExceptionEventHandler就是一個通知性質的事件,沒有處理異常的功能,自然未處理異常還會是程式崩潰。它的UnhandledExceptionEventArgs中有兩個屬性:IsTerminating和ExceptionObject,分別代表程式是否在崩潰和引起崩潰的異常對象。
比如這段代碼:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
throw new Exception("test");
}
static void 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應用程式了。
比如在按鈕點擊後拋出一個異常:
private void Button_Click(object sender, RoutedEventArgs e)
{
Dispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
throw new Exception("test");
}
void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "錯誤", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
}
結果:
一個訊息框出現,關閉後程式繼續運行。