1. 程式人生 > >異常和狀態管理2

異常和狀態管理2

起點 檢查 導致 有用 eth 調用 指令 class trace

System.Excelption 類型提供的制度 StackTrace 屬性。

catch 塊可讀取該屬性來獲取一個堆棧跟蹤,它描述了異常發生前調用了哪些方法。檢查異常原因並改正代碼時,這些信息很有用。訪問該屬性實際會調用 CLR 中的代碼;該屬性不是簡單的放回一個字符串。構造 Exception 派生類型的新對象時,StackTrace 屬性被初始化為 null。如果此時讀取該屬性,得到的不是堆棧跟蹤,而是一個 null。

一個異常拋出時,CLR 在內部記錄 throw 指令的位置(拋出位置)。一個 catch 塊捕捉到該異常時,CLR 記錄捕捉位置。在 catch 塊內訪問被拋出的異常對象的 StackTrace 屬性,負責實現該屬性的代碼會調用 CLR 內部的代碼,後者創建一個字符串來指出從異常拋出位置到異常捕捉位置的所有方法。

(拋出異常時,CLR 會重置異常起點;也就是說,CLR 只記錄最新異常對象的拋出位置。)

以下代碼拋出它捕捉到的相同的異常對象,導致 CLR 重置該異常的起點:

private void SomeMethod()
{
    try{...}      
    catch(Exception e) {
         throw e;// CLR 認為這是異常的起點,FxCop報錯      
    }    
}

但如果僅僅適用 throw 關鍵字本身(刪除後面的 e)來重新拋出異常對象,CLR 就不會重置堆棧的起點。

實際上,兩端代碼唯一的區別就是 CLR 對於異常起始拋出位置的認知。遺憾的是,不管拋出還是重新拋出,Windows 都會重置棧的起點。詳見(CLR Via C# 4.0 P408)。

異常和狀態管理2