關於異常,記錄一些看到的和自己總結的
for (int i = 0; i <= 2; i++)
{
try
{
int number = Convert.ToInt32("aa");
}
catch (Exception ex)
{
throw new MyUserException(ex.Message);
}
}
MyUserException是自訂的異常類,把異常資訊記入到異常文本error.txt
public class MyUserException : Exception
{
private string messageinfo = string.Empty;
public MyUserException(string message)
: base(message)
{
messageinfo = message;
OperateException(message);
}
private void OperateException(string message)
{
string path = Directory.GetCurrentDirectory() + @"\error.txt";
if (File.Exists(path))
{
FileStream nFile = new FileStream(path, FileMode.Open);
StreamWriter sw = new StreamWriter(nFile);
sw.WriteLine(message);
sw.Close();
}
}
}
這是一個很常見的異常捕捉,但是如此的拋出異常並同時寫入異常文本後,程式會終止。我們也可以在catch中不用拋出異常,也可寫一個異常操作類,專門寫入異常資訊,可讓程式繼續進行,但是我經常看到大家在問一個問題就是:如何讓存在異常後,讓程式繼續進行。
我看到很多人的回答是catch中不寫任何代碼,這樣回答其實是不負責任的,很多情況下,比如下列代碼
try
{
for (int i = 0; i <= 2; i++)
{
int number = Convert.ToInt32("aa");
}
}catch ()
{
}
String name=”xxx”;
這裡我把異常捕捉寫在迴圈外面,如果只是簡單的catch中不寫任何代碼就讓程式繼續執行迴圈體,顯然這裡是做不到的,程式會繼續往下執行String name=”xxx”;而不會去執行迴圈體,所以我們可以考慮把異常捕捉寫到迴圈體內,catch中什麼都不寫,或者寫continue讓迴圈繼續
for (int i = 0; i <= 2; i++)
{
try
{
int number = Convert.ToInt32("aa");
}
catch ()
{
}
}
其實異常捕捉有人說太多try會影響效能,但是實際上,有try和沒有try效能差不多,只是在偶爾出現異常後,執行到catch時會消耗很多時間,但是事實上異常並不時時發生,用這點時間換取捕捉到的異常還是值得的,只要你不要把異常捕捉作為程式的邏輯設計,但是不可以否認的是有try catch在編譯時間是需要耗一些時間的,因為編譯模式內要回填異常的處理地址。
.net在產生異常時是逐步向外層尋找處理常式的,因此可以說捕獲的越早效率越高.如果當前應用程式沒有對異常進行處理,就交給runtime,在這種情況下,效率才是最低的,而且比較難於處理。
我曾經看過一篇文章,講述的是拋出異常時,是catch內部拋出執行個體化異常類效率高,還是在catch調用靜態方法,然後在靜態方法中拋出異常效率高,例如
private int GetItOne(int key) {
int value;
if (!_dict.TryGetValue(key,out value)) {
throw new ArgumentOutOfRangeException("key");
}
return value;
}
和
private int GetItTwo(int key) {
int value;
if (!_dict.TryGetValue(key, out value)) {
ThrowArgumentOutOfRangeException();
}
return value;
}
private static void ThrowArgumentOutOfRangeException() {
throw new ArgumentOutOfRangeException("key");
}
所以說如果自訂一個靜態異常類,然後throw還是有優勢的。
參見
http://www.cnblogs.com/tansm/archive/2012/05/13/dotnet_profile1.html#commentform