WPF全局異常捕獲

 在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 += new UnhandledExceptionEventHandler( 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());
        }

void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            //task線程內未處理捕獲
            MessageBox.Show("捕獲線程內未處理異常:" + args.Exception.Message);            
            args.SetObserved();//設置該異常已察覺(這樣處理後就不會引起程序崩潰)
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章