WPF捕獲全局未處理異常
阿新 • • 發佈:2017-10-25
system 用戶界面 startup blog log 未處理 eve -s ebo
在WPF開發過程中我們一般都用try/catch塊來捕獲異常,但不是每個異常我們都能捕獲,程序總會出現一些意想不到情況,拋出一些未捕獲的異常,這時就要用到全局異常捕獲,即在程序的最外層加上捕獲未處理異常,以免程序奔潰,影響用戶體驗。
在WPF應用程序中,會有兩大類未處理異常:一類是在UI線程拋出來的,例如點擊了用戶界面上面的某個控件,然後執行某個代碼的時候,遇到了異常;另一類是非UI線程跑出來的,例如在一個多線程的程序裏面,工作線程的代碼遇到了異常。
對於UI線程的未處理異常,我們用Application.DispatcherUnhandledException事件來處理,對於非UI線程的未處理異常用 AppDomain.UnhandledException事件來處理,對於Task內未處理異常用TaskScheduler.UnobservedTaskException事件來處理;
下面看代碼:
public App() { //首先註冊開始和退出事件 this.Startup += new StartupEventHandler(App_Startup); this.Exit += new ExitEventHandler(App_Exit); }
啟動事件對應的方法:
void App_Startup(object sender, StartupEventArgs e) {//UI線程未捕獲異常處理事件 this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
//Task線程內未捕獲異常處理事件
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
//非UI線程未捕獲異常處理事件 AppDomain.CurrentDomain.UnhandledException += newUnhandledExceptionEventHandler( CurrentDomain_UnhandledException); }
退出事件對應的方法:
void App_Exit(object sender, ExitEventArgs e) { //程序退出時需要處理的業務 }
具體對應的方法:
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { try { e.Handled = true; //把 Handled 屬性設為true,表示磁異常已處理,程序可以繼續運行,不會強制退出 MessageBox.Show("捕獲未處理異常:" + e.Exception.Message); } catch (Exception ex) { //此時程序出現嚴重異常,將強制結束退出 MessageBox.Show("程序發生致命錯誤,將終止,請聯系運營商!"); } } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { StringBuilder sbEx = new StringBuilder(); if (e.IsTerminating) { sbEx.Append("程序發生致命錯誤,將終止,請聯系運營商!\n"); } sbEx.Append("捕獲未處理異常:"); if (e.ExceptionObject is Exception) { sbEx.Append(((Exception)e.ExceptionObject).Message); } else { sbEx.Append(e.ExceptionObject); } MessageBox.Show(sbEx.ToString()); Loger.WriteErrorLog("捕獲未處理異常:" + e.ExceptionObject); } void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { //task線程內未處理捕獲 MessageBox.Show("捕獲線程內未處理異常:" + args.Exception.Message); Loger.WriteErrorLog("捕獲線程內未處理異常:" + args.Exception); args.SetObserved();//設置該異常已察覺(這樣後就不會引起程序崩潰) }
WPF捕獲全局未處理異常