1.寫在前面java
「異常意味着什麼?」,想必不用對此作多餘的解釋,咱們有理由相信在任何狀況下任何應用程序都有可能出現異常,若在程序中沒有對異常進行處理,則操做系統會以粗暴的方式處理掉它(彈出錯誤提示框),在不少應用軟件中均可以看到這樣的提示框,無疑會影響用戶的體驗。因此,咱們徹底有必要對應用程序進行全方位的異常處理,儘量地覆蓋全部可能出現的異常,而程序的異常處理自己是一個很是重要卻極易被忽視的問題。windows
2.通常的異常處理方式app
無非就是try...catch...finally...的應用,把全部自認爲可能出現異常的代碼都用try塊wrap起來,沒錯,這確實是一種徹底可行的方法,但卻不是最合適的作法。緣由以下:函數
假如須要開發一個WinForm應用程序,首先生成項目時VS自動生成機器代碼,而後編碼人員進行編碼,實現須要的功能,編碼人員很是謹慎,因此他在本身編寫的代碼中添加了若干個異常處理塊。。。不管怎麼測試都沒有出現未被捕獲的異常,他很開心,但是有一天運行應用程序時仍是發生了異常,這是爲何?答案是編碼人員沒錯,VS生成的機器代碼也沒錯,而是操做系統出錯了,在加載該APP時可能遇到了Interruption,進而引起了異常(固然,只是舉個例子)學習
咱們能夠看到,若撇開系統異常以及RunTimeException不講,編碼人員作得很是好,這樣的作法是值得咱們學習的,也必須養成這樣的習慣。測試
3.對於通常異常處理的建議編碼
在上面介紹的通常的異常處理方式中,咱們不得不須要關注代碼臃腫的問題,try...catch...finally...無疑會佔用很大篇幅,這個是能夠避免的,能夠把異常儘可能集中處理,推薦的作法是對下層的Exception直接throw出去(在函數定義時添上throws聲明便可),在Main函數中統一處理(由於到這裏就不能繼續throw了,不然。。。)spa
其次在catch塊處理異常時,咱們能夠新建一個獨立的ExceptionClass定義各類異常的處理方法,避免出現大量冗餘代碼操作系統
每一個線程都要對應一個異常處理方法,Main屬於主線程,在自定義的子線程裏應該使用獨立的異常處理線程
4.集中式異常處理
上面的第一條建議只適合控制檯應用程序,不存在複雜的人機交互,對於WinForm應用程序將再也不適用,那麼在WinForm應用程序中怎樣合理地處理異常?
C Sharp的Application.ThreadException爲咱們提供了便利,用於處理UI線程異常,AppDomain.CurrentDomain.UnhandledException用於處理非UI線程異常
用法以下:
1 static class Program 2 { 3 /// <summary> 4 /// 應用程序的主入口點。 5 /// </summary> 6 [STAThread] 7 [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)] 8 static void Main() 9 { 10 Application.EnableVisualStyles(); 11 Application.SetCompatibleTextRenderingDefault(false); 12 //處理未捕獲的異常,始終將異常傳送到 ThreadException 處理程序 13 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 14 //集中處理異常 15 //訂閱ThreadException事件,處理UI線程異常,處理方法爲handler1 16 Application.ThreadException += new ThreadExceptionEventHandler(handler1); 17 //訂閱UnhandledException事件,處理非UI線程異常,處理方法爲handler2 18 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(handler2); 19 20 Application.Run(new MainForm()); 21 } 22 23 public static void handler1(object sender, ThreadExceptionEventArgs e) 24 { 25 MessageBox.Show("哎呀,好像出錯了T_T"); 26 Application.Exit(); 27 } 28 29 public static void handler2(object sender, UnhandledExceptionEventArgs e) 30 { 31 MessageBox.Show("哎呀,好像出錯了T_T"); 32 Application.Exit(); 33 } 34 }
特別說明:
1>請注意Main方法裏各個語句的順序,集中異常處理的相關代碼必須放在Application.Run();語句以前,不然沒有效果
2>以上代碼都在program.cs中,由於程序入口Main在這裏
3>若對這樣的處理方式還存在疑問,能夠查看官方文檔以及例程序源碼http://msdn.microsoft.com/zh-cn/library/system.windows.forms.application.setunhandledexceptionmode.aspx
5.最後的建議(請務必看看)
1>集中式異常處理並非萬能的,不建議過度依賴這樣的處理方式
2>集中式異常處理只是最後的一道防線,程序內部仍然應該添加儘量完善的異常處理
3>任何異常處理都應該包括兩個部分,即A.記錄異常信息(寫入ErrorLog或者發送到做者郵箱等等)B.善後操做(退出APP或者其它補救處理)