關於C_Sharp集中處理異常

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或者其它補救處理)

相關文章
相關標籤/搜索