幾條建議:
若是沒法處理某個異常,那就不要捕獲它。
若是捕獲了一個異常,請不要胡亂處理它。
儘可能在靠近異常被拋出的地方捕獲異常。
在捕獲異常的地方將它記錄到日誌中,除非您打算將它從新拋出。
按照您的異常處理必須多精細來構造您的方法。
須要用幾種類型的異常就用幾種,尤爲是對於應用程序異常。
把低層次的異常封裝成層次較高程序員較容易理解的異常。
儘可能輸出形成異常的完整數據
儘可能捕獲具備特定含義的異常:好比SqlException,而不是簡單地捕獲一個Exception。php
若是你的程序不是對效率苛求得過度,我建議你寧肯多使用一些異常也是好的。
注意:我說的多使用的意思不是讓你所有trycatch起來,而後catch(Exception e)把全部的異常都屏蔽了;而是暫時不考慮trycatch可能帶來的效率上的損失,而注重程序的穩定性。
至於如何優化trycatch的使用,慢慢來。就我我的的使用而言,影響其實不是很大。程序員
1. 不要濫用Try…Catch。通常來講只在最外層函數上才須要。由於該函數不能將Exception再往外拋了。因此須要Catch住作相應的處理,如顯示Error Message。或轉化爲與調用模塊約定好的Error Code。內部函數即便Catch住了Exception,也要往外拋,因此沒有必要。api
2. 爲了使用Finally來保證資源的釋放。如:服務器
SqlConnection connection = null;函數
try工具
{學習
connection = new SqlConnection(ConnectionString);優化
connection.Open();spa
…開放源代碼
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (connection != null && connection.State != ConnectionState.Closed)
{
connection.Close();
}
}
對這種狀況Catch住的Exception直接往外拋,不作處理。須要注意的是這裏使用Try…Catch不是惟一的辦法,也可使用using語句來保證資源的釋放。
3. 爲了保證函數有統一的出口。好比一個最外層的函數連續調用了一系列內部子函數,當其中某個子函數出錯時, 跳到函數最後退出,對這種狀況Catch住的Exception直接吃掉,由於在Try裏面已經作了錯誤處理。如:
public Result OutMostFunction()
{
Result result = Result.Success;
try
{
try
{
SubFunction1();
}
catch (Exception ex)
{
result = Result.SubFunction_1_Error;
throw ex;
}
try
{
SubFunction2();
}
catch (Exception ex)
{
result = Result.SubFunction_2_Error;
throw ex;
}
try
{
SubFunction3();
}
catch (Exception ex)
{
result = Result.SubFunction_3_Error;
throw ex;
}
}
catch (Exception ex)
{
}
return result;
}
4. 爲了區分程序錯誤與邏輯錯誤,須要自定義一個Exception類型。好比一個最外層函數調用一個密碼驗證子函數,就須要區分是由於密碼錯誤(邏輯錯誤),仍是在密碼驗證過程當中程序出現了沒有預料到的錯誤(程序錯誤)。如:
public class GoOutException : Exception {}
public Result OutMostFunction()
{
Result result = Result.Success;
try
{
try
{
if (!VerifyPassword(password))
{
result = Result.Invalid_Password;
throw new GoOutException();
}
}
catch (Exception ex)
{
if (!(ex is GoOutException))
{
result = Result.General_Error;
}
throw ex;
}
}
catch (Exception ex)
{
}
return result;
}