異常處理—Exception(二)

在上一篇中"異常處理--Exception(一)"中,跟你們簡單介紹了一下Exception,也使你們充分的瞭解了Exception管理在一個項目中的重要性,那如何在咱們的項目中處理異常呢?由於我從事的是Web開發,因此我只跟你們討論Web的解決方案,Win的解決方式,還但願同你們一塊兒探討。html

上一章中咱們瞭解了異常發生的緣由,同時也說了不存在沒有bug的程序,任何網站都會遇到各類各樣的問題,不管是大網站仍是小網站都會存在,但大公司和小公司對待異常的態度全然不一樣,一個是主動出擊,一個是守株待兔,咱們是好的開發者,咱們不能坐以待斃,咱們必須主動出擊。好了,廢話少說,切入主題。數據庫

如今網站通常都採用多層開發,多層開發的時候,咱們應該在哪裏處理異常、在拋出異常呢?微軟的意見是類庫的開發人員儘可能不要處理異常,類庫的編寫應該按照正常的邏輯去編寫,固然也有例外,注意事項能夠參見"設計異常解決方案的幾點注意事項",好的,按照規範,咱們應該儘可能在高層進行捕捉和處理,那咱們該怎麼捕捉,捕捉後怎麼處理,捕捉哪些異常呢?雖然微軟提供了不少系統異常,可是這些異常只是負責拋出相關的信息,並無爲記錄下來,或者出現高級異常的時候,及時通知咱們,這樣的作法仍是守株待兔,咱們仍是應該主動的對其進行處理。好在微軟讓咱們能夠自由的建立自定義的Exception,最好是設定一個自定義Exception基類,讓你的其餘自定義Exception都繼承這個類,以便從此更好的擴展。拋出異常實際上是性能消耗很大的操做,可是Richer教父說過,拋出異常的性能和你程序的穩定性相比,就變得很是眇小了。因此咱們仍是偏向於穩定性。由於處理異常的性能消耗,只是在異常發生時才產生,因此性能方面的問題,咱們能夠忽略了。(或許這話比較拗口,但相比系統的性能,我更趨向於系統的穩定)安全

   

如何建立一個自定義的Exceptionpost

不得不說微軟考慮的太周到了,要建立一個自定義的Exception是很是簡單的。打開VS,建立一個項目,而後添加一個類,在namespace範圍內,輸入Exception,而後2TabVS就自定幫您建立一個自定義的Exception了。Exception的相關屬性和方法,能夠參見MSDN。不過自動建立的Exception都是繼承System.Exception的,按照微軟當初的設想,自定義的異常應該繼承System.ApplicationException (好笑的是,微軟本身都沒有遵照這個約定)。咱們設定這個做爲咱們的Exception基類MyBaseException性能

代碼片段:網站

[global::System.Serializable] ui

public class MyBaseException : ApplicationException spa

{ 設計

public MyBaseException() { } 日誌

public MyBaseException(string message) : base(message) { }

public MyBaseException(string message, Exception inner) : base(message, inner) { }

protected MyBaseException(

System.Runtime.Serialization.SerializationInfo info,

System.Runtime.Serialization.StreamingContext context)

: base(info, context) { }

}

這就是一個標準的自定義Exception了,至於其它的自定義Exception,應該根據你的項目來進行相關的定義。

在進行其餘定義以前,咱們先來想一想,咱們捕捉這些Exception以後咱們須要作些什麼?咱們須要知道異常發生的各類信息,因此咱們須要LogLog能方便的讓咱們查閱發生的異常及Log的異常信息。Log有不少方式,大概的有如下幾種:

文本記錄

數據庫記錄

系統事件記錄(Trace

第三方組件(Log4Net

這幾種方式各有利弊,能夠根據項目的需求進行選擇,固然你也能夠幾種方式合用,好比咱們默認的是文本記錄方式,可是在建立Log時發生了System.IOException,咱們就必須選擇其餘的方式進行Log

Log方式

便捷性

查閱性

安全性

結合性

文本記錄

方便

通常

數據庫記錄

通常

方便

通常

系統事件記錄

複雜

複雜

通常

第三方組件

複雜

通常

通常

我列舉了幾種方式的利弊,你們能夠有條件的選擇。若是你的項目中已經使用第三方組件記錄方式,那我建議您使用它。在我後面的解決方案中,我會利用前2種比較常見的方式相結合。

Log的目的是爲咱們開發者提供發生異常的時間、地點、人物、緣由,因此咱們必須儘量的詳細地記錄,根據一個Exception獲取信息的方法:

Data

Source

Dates and Times

DateTime.Now

Source of Exception

Exception.Source

Type of Exception

Object.GetType

Exception Message

Exception.Message

Current Method

Reflection.MethodInfo.GetCurrentMethod

Machine Name

Environment.MachineName or Dns.GetHostName

CurrentIP

Dns.GetHostByName("host").AddressList[0].Address

Call Stack

Exception.StackTrace or Environment.StackTrace

OS Information

Environment.OSVersion

Applcation Domain

AppDomain.FriendlyName

Current Assembly

Reflection.Assembly.GetExecutingAssembly

Root Error Cause

Exception.GetBaseException

Chained Exception

Exception.InnerException

Assembly Version

Included in AssemblyName.FullName

Thread ID

AppDomain.GetCurrentThreadId

Thread User

Threading.Thread.CurrentPrincipal

咱們能夠根據上面的表格,構建咱們本身所須要的Log信息。爲了便捷的管理,咱們應該採用同一格式,進行Log。這裏貼一個我寫的信息格式,以供參考:

public static class ExceptionLogFormatHelper

{

public static string ExceptionLogFormatter(Exception ex)

{

StringBuilder sbLog = new StringBuilder("\r\n------------------------------------\r\n");

Exception ochainException = ex;

var currentExceptionIndex = 1;

while (ochainException != null)

{

   

sbLog.Append("\r\nException " + currentExceptionIndex + " )")

.Append("\r\nException Type:" + ochainException.GetType().FullName)

.Append("\r\nException Source:" + ochainException.Source)

.Append("\r\nException Message:" + ochainException.Message)

.Append("\r\nException Date:" + DateTime.Now)

.Append("\r\nEnvironment Stack:" + System.Environment.StackTrace);

ochainException = ochainException.InnerException;

currentExceptionIndex++;

}

sbLog.Append("\r\n------------------------------------\r\n");

return sbLog.ToString();

}

}

你也能夠根據你本身想要的信息構建這麼一個方法。

這一篇廢話多了點,不過仍是有必要了解下。還介紹了自定義異常的建立,日誌方式的對比,在下一篇,我將介紹通知、異常處理流程和定義本身的一個MyBaseException

==

相關文章
相關標籤/搜索