MS Enterprise Library 6.0 (三) - Exception Handling Application Block
有時候心情好,忍不住就多寫幾篇Blog。(當然,心情比較差的時候,可能十天半個月沒辦法安安靜靜的把一些東西整理出來)
前面錄了兩段Enterprise Library的介紹影片,分別談了Unity Application Block和Logging Application Block,這一篇緊接著談Exception Handling Application Block。
由於時空的限制,我現在所在的位置沒法錄製影片,所以只好乖乖用寫的了。
如果可以讓我選擇,我喜歡錄影片遠超過寫文字,原因很簡單,因為我話多,blog有時候忍不住就多寫了幾百字,但這年頭大家都不看字的,害我覺得寫了很無聊。寫了沒人看不打緊,花的時間很多,年紀大了越來越懶,用講的比較快,還可以當作上課的彩排甚至教材,所以我喜歡錄影遠超過寫文章。
岔題了。
Exception Handling Application Block,顧名思義就是系統中處裡例外的模塊,大家都知道,我們會在程式碼中加上try...catch來處理例外,程式碼常常會像是這樣:
但如果像上面這樣的程式碼一多,我們就會發現,每一個try...catch裡面都是另一段不受管理的複雜的錯誤處裡邏輯,可能是寫log、可能是發mail、可能是retry...,不僅如此,一旦例外處理區塊寫死之後,例外處理區塊常常本身就是一個大累贅。
還有,發生例外的可能性和類型很多元,上面這段程式碼非常簡單,只可能得到一個 "除以零" 錯誤。但真實世界中,如果是一段比較複雜的程式碼,有網路連線、有檔案處理、有數字計算、日期計算...而我們要針對可能發生的不同的例外分開來處理(例如發生檔案相關錯誤就發mail、發生網路錯誤就寫file log,發生其他運算錯誤就寫event log...,那你的catch中的程式碼就精彩了!!!
也因此,我們需要一個一致性的例外管理模塊,這時候, Exception Handling Application Block 就可以派上用場了。Exception Handling Application Block 可以做到:
OK,所以瞭解了程式碼之後,就知道關鍵在名稱為Policy的設定檔內容,這個設定檔的內容決定了我們要如何處理、以及要處理哪些類型的例外,並且決定了處裡完例外之後,是否要重新丟出例外。
知道了之後,我們就來看如何建立這個設定檔,請參考底下的影片,我們的動作是:
btw, 請原諒我只能很扼要的介紹Enterprise Library中的exception handling application block,其他更多精彩的功能,請自行參考微軟Enterprise Library網站囉。
前面錄了兩段Enterprise Library的介紹影片,分別談了Unity Application Block和Logging Application Block,這一篇緊接著談Exception Handling Application Block。
由於時空的限制,我現在所在的位置沒法錄製影片,所以只好乖乖用寫的了。
如果可以讓我選擇,我喜歡錄影片遠超過寫文字,原因很簡單,因為我話多,blog有時候忍不住就多寫了幾百字,但這年頭大家都不看字的,害我覺得寫了很無聊。寫了沒人看不打緊,花的時間很多,年紀大了越來越懶,用講的比較快,還可以當作上課的彩排甚至教材,所以我喜歡錄影遠超過寫文章。
岔題了。
Exception Handling Application Block,顧名思義就是系統中處裡例外的模塊,大家都知道,我們會在程式碼中加上try...catch來處理例外,程式碼常常會像是這樣:
try { int a = 10, b = 0; a = a / b; Console.WriteLine("done!"); Console.ReadKey(); } catch (Exception ex) { //如果發生例外...就... }這樣的程式碼沒啥太大的問題(除了因為是範例所以一定會發生例外之外...)。
但如果像上面這樣的程式碼一多,我們就會發現,每一個try...catch裡面都是另一段不受管理的複雜的錯誤處裡邏輯,可能是寫log、可能是發mail、可能是retry...,不僅如此,一旦例外處理區塊寫死之後,例外處理區塊常常本身就是一個大累贅。
還有,發生例外的可能性和類型很多元,上面這段程式碼非常簡單,只可能得到一個 "除以零" 錯誤。但真實世界中,如果是一段比較複雜的程式碼,有網路連線、有檔案處理、有數字計算、日期計算...而我們要針對可能發生的不同的例外分開來處理(例如發生檔案相關錯誤就發mail、發生網路錯誤就寫file log,發生其他運算錯誤就寫event log...,那你的catch中的程式碼就精彩了!!!
try { //如果這邊很長,或是進行了各種不同的動作 } catch (Exception ex) { //如果是DivideByZeroException if (ex.GetType().Equals(typeof(System.DivideByZeroException))) { //... } //如果是WebException if (ex.GetType().Equals(typeof(System.Net.WebException))) { //... } //如果是FileLoadException if (ex.GetType().Equals(typeof(System.IO.FileLoadException))) { //... } }所以可以想見,當我們在真實世界的專案當中,catch部分可能要針對各種不同型態的例外,進行各種不同的處理,再加上又要考慮是否rethrow,複雜度又更高了...
也因此,我們需要一個一致性的例外管理模塊,這時候, Exception Handling Application Block 就可以派上用場了。Exception Handling Application Block 可以做到:
- 用統一的程式碼來管理例外
- 透過設定App.Config來處理例外,如此一來若要改變例外處理的方式,就可以不用改程式碼
- 可針對不同類型的例外設定不同的處裡方式
- 可隨時增加或減少某種例外的處理方式(例如發生例外時的紀錄本來只有發email,但要改成同時寫入db,可以透過設定的方式來進行)
知道了用途之後,我們就來看看實際上怎麼用。
Step1:現在專案中加入:
- Exception Handling Application Block
- Exception Handling Application Block Logging Handler
- Logging Application Block
本來我們只需要加入第1個,但因為我們處理Exception的方法是寫Log,因此也加入了2,3
Step2:請參考底下的程式碼:
底下這段程式碼是Console Application,基本上3-10行是Enterprise Library的相關程式碼,主要是從設定檔來建立所需要的各種物件。(待會會教大家如何建立設定檔)
16行是會觸發一個除以零錯誤的代碼
而23,24則是我們的核心了,我們透過ExceptionPolicy這個 enterprise library的錯誤處理類別,來處理錯誤,採用的是名稱為Policy的設定檔內容。
16行是會觸發一個除以零錯誤的代碼
而23,24則是我們的核心了,我們透過ExceptionPolicy這個 enterprise library的錯誤處理類別,來處理錯誤,採用的是名稱為Policy的設定檔內容。
-------------------------------------------------
static void Main(string[] args) { //抓取Config檔案中的設定,作為configurationSource IConfigurationSource configurationSource = ConfigurationSourceFactory.Create(); //以Config檔案中的設定,建立logWriterFactory LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource); //以Config檔案中的設定,建立LogWriter Logger.SetLogWriter(logWriterFactory.Create()); //以Config檔案中的設定,建立ExceptionManager ExceptionPolicy.SetExceptionManager(new ExceptionPolicyFactory(configurationSource).CreateManager(), true); //故意寫一段會錯的程式碼 try { int a = 10, b = 0; a = a / b; Console.WriteLine("done!"); Console.ReadKey(); } catch (Exception ex) { //以Config檔案中的 "Policy" ExceptionPolicy設定來處理 var rethrow = ExceptionPolicy.HandleException(ex, "Policy"); //如果設定檔說要重丟例外,就重丟 if (rethrow) throw; } }--------------------------------------------------------
OK,所以瞭解了程式碼之後,就知道關鍵在名稱為Policy的設定檔內容,這個設定檔的內容決定了我們要如何處理、以及要處理哪些類型的例外,並且決定了處裡完例外之後,是否要重新丟出例外。
知道了之後,我們就來看如何建立這個設定檔,請參考底下的影片,我們的動作是:
- 從VS2012開啟設定檔編輯器
- 建立Exception Handling Settings( 注意名稱為 Policy,且post HandlingAction設為None )
- 建立Logging Exception Handler(配合Exception Handling Settings)
- 在Logging Exception Handler中,指定Logging Settings( 注意名稱為 General )
- 建立Rolling Flat File Trace Listener
最後,我們來看執行結(請留意,當修改了設定檔之後重新執行,你會發現程式對錯誤的處裡方式也隨著設定檔而蓋變了):
留言
再次感謝您。
C.K. Hsieh