一、ASP.NET中需要引發異常的四類情況
1、如果運行代碼后,造成內存泄漏、資源不可用或應用程序狀態不可恢復,則引發異常。Console這個類中,有很多類似這樣的代碼:
if((value<1)||(value>100)) {thrownewArgumentOutOfRangeException("value", value, Environment.GetResourceString("ArgumentOutOfRange_CursorSize")); }
2、在捕獲異常的時候,如果需要包裝一些更有用的信息,則引發異常。這類異常的引發在UI層特別有用。系統引發的異常所帶的Message往往更傾向于技術性的描述,而在UI層,異常的用戶很可能是最終用戶。如果我們需要將異常的Message信息呈現給最終用戶,更好的做法是包裝異常,然后引發一個含有友好信息的新異常。
3、如果底層異常在高層操作的上下文中沒有意義,則可以考慮捕獲這些底層異常,并引發新的有意義的異常。如將一個InvalidCastException引發為新的ArgumentException。
4、捕獲底層API錯誤代碼,并拋出。Console為我們封裝了調用windows api返回的錯誤代碼,而讓代碼引發一個新的異常。
二、ASP.NET系統自帶的異常類
1、Exception 所有異常對象的基類2、SystemException 運行時產生的所有錯誤的基類3、IndexOutOfRangeException 當一個數組的下標超出范圍時運行時引發4、NullReferenceException 當一個空對象被引用時運行時引發
5、InvalidOperationException 當對方法的調用對對象的當前狀態無效時,由某些方法引發6、ArgumentException 所有參數異常的基類7、ArgumentNullException 在參數為空(不允許)的情況下,由方法引發8、ArgumentOutOfRangeException 當參數不在一個給定范圍之內時,由方法引發
9、InteropException 目標在或發生在CLR外面環境中的異常的基類10、ComException 包含COM 類的HRESULT信息的異常11、SEHException 封裝win32 結構異常處理信息的異常
三、ASP.NET中異常處理注意事項
1、避免在finally內撰寫無效代碼
你應該始終認為finally內代碼會在方法return之前被執行,哪怕return是在try塊中。但,需要區分引用類型變量和值類型變量在finally中會導致不同結果。
例如
C# 代碼 復制PRivate static int TestIntReturnInTry()
{
int i;
try
{
return i = 1;
}
finally
{
i = 2;
Console.WriteLine("http://t將int結果改為2,finally執行完畢");
}
}
它返回的將是1。代碼中,i=2實際上是一段無效代碼,如果編譯采用Release模式,編譯器會直接將i=2刪除,它不會為其生成對應的IL代碼。
但是:
C# 代碼 復制static User TestUserReturnInTry()
{
User user = new User() { Name = "Mike", BirthDay = new DateTime(2010, 1, 1) };
try
{
return user;
}
finally
{
user.Name = "Rose";
user.BirthDay = new DateTime(2010, 2, 2);
Console.WriteLine("http://t將user.Name改為Rose");
}
}
TestUserReturnInTry方法返回的User中,Name的值已經改變為Rose了。
2、避免嵌套異常
應該允許異常在調用堆棧中往上傳播,不要過多使用catch,然后再throw。無故地嵌套異常是我們要極力避免的。
3、避免“吃掉”異常
避免“吃掉”異常,并不是說不應該“吃掉”異常,而是這里面有個重要原則:該異常可悲預見,并且通常情況它不能算是一個Bug。
想象你正在對上萬份文件進行解密,這些文件來自不同的客戶端,很有可能存在文件倍破壞的現象,你的目標就是要講解密出來的數據插入數據庫。這個時候,你不得不忽略那些解密失敗的問題,讓這個過程進行下去。當然,記錄日志是必要的, 因為后期你可能會倍解密失敗的文件做統一的處理。
另外一種情況,可能連記錄日志都不需要。在對上千個受控端進行控制的分布式系統中,控制端需要發送心跳數據來判斷受控端的在線情況。通常的做法是維護一個信號量,如果在一個可接受的阻滯時間如(如500ms)心跳數據發送失敗,那么控制端線程將不會收到信號,即可以判斷受控端的斷線狀態。在這種情況下,對每次SocketException進行記錄,通常也是沒有意義的。
如果你不知道如何處理某個異常,那么千萬不要“吃掉”異常,如果你一不小“吃掉”了一個本該網上傳遞的異常,那么,這里可能誕生一個BUg,而且,解決它會很費周折。
4、避免在調用棧較低位置記錄異常
最適合進行異常記錄和報告的是應用程序的最上層,這通常是UI層。假設存在這樣的一個應用程序,它的BLL層,即可能被一個Winform窗口程序調用,也可能被一個控制臺應用程序調用,那么如果要在BLL模塊向管理員報告異常的時候,你不知該使用MessageBox方法還是Console.Write方法。
如果異常在調用棧的較低位置被記錄或報告,且還存在被包裝后重新拋出的情況,這就會讓記錄重復出現。
5、不要再從System.applicationExcetipn這個基類派生異常
微軟自己也已經修正這一點,當前的建議是:從System.Exception或其它常見基本異常之一派生異常。事實上,現在如果你在Visual studio中輸入Excetion,然后使用快捷鍵tab,vs會自動給你創建一個繼承自System.Exception的自定義異常類
四、ASP.NET中異常處理的其它建議
1、當引發異常時,要提供有意義的文本。2、要引發異常僅當條件是真正異常;也就是當一個正常的返回值不滿足時。3、如果你的方法或屬性被傳遞一個壞參數,要引發一個ArgumentException異常。
4、當調用操作不適合對象的當前狀態時,要引發一個InvalidOperationException異常。5、要引發最適合的異常。6、要使用鏈接異常,它們允許你跟蹤異常樹。
7、不要為正常或預期的錯誤使用異常。8、不要為流程的正常控制使用異常。9、不要在方法中引發NullReferenceException或IndexOutOfRangeException異常。
新聞熱點
疑難解答