c# - catch(Exception ex) 會丟掉StackTrace 是怎么回事?


原本這篇文章就想寫寫StackTrace怎么會丟的問題, 但現在的內容變成了討論怎么處理Exception的問題。

該不該用try catch, 什么時候用?也困擾了我很久, 好像隨便寫寫就可以, 但是事實上還是有Best Practise, 以下內容請您參考,歡迎指正!


StackTrace: 保存方法的棧調用信息。

什么意思呢?A方法里調用了B方法,B方法里調用了C方法,你調用A方法的時候StackTrace里就大概是這樣:

at Project.Class.C in c:\aaa\Project\class.cs:line 10.

at Project.Class.B in c:\aaa\Project\class.cs:line 20.

at Project.Class.A in c:\aaa\Project\class.cs:line 30.

它就是個字符串。

 

不過他有什么用呢?你說呢,畢竟人家連行號都告訴你了。如果丟了StackTrace,我們也就丟了這些信息。

 

什么情況下會丟StackTrace?看看這段代碼:

[csharp]  view plain  copy
 
 print?
  1. static void Main(string[] args)  
  2.        {  
  3.            try  
  4.            {  
  5.                // Call Method1  
  6.                Console.WriteLine(Method1());  
  7.            }  
  8.            catch (Exception ex)  
  9.            {  
  10.                Console.WriteLine(ex.StackTrace);  
  11.            }  
  12.            Console.ReadLine();  
  13.        }  
  14.   
  15.        public static int Method1()  
  16.        {  
  17.            try  
  18.            {  
  19.                return Method1_1();  
  20.            }  
  21.            catch (Exception ex)  
  22.            {  
  23.                throw ex;  
  24.            }  
  25.        }  
  26.   
  27.        public static int Method1_1()  
  28.        {  
  29.            int j = 0;  
  30.            return 10 / j;  
  31.        }  


乍看貌似沒有什么問題,但是Method1多做了一件事: Catch(Exception ex){thorw ex;}

他帶來一個后果就是,StackStace會丟.

 

得到的StackTrace如下:

   at ExceptionMethodCall.Program.Method1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 33
   at ExceptionMethodCall.Program.Main(String[] args) in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 16

刪除 try..catch, 我們得到的StackTrace如下:

   at ExceptionMethodCall.Program.Method1_1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 40
   at ExceptionMethodCall.Program.Method1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 29
   at ExceptionMethodCall.Program.Main(String[] args) in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 16

結果顯而易見。

 

更多:

如果Method1代碼這么寫:

[csharp]  view plain  copy
 
 print?
  1. public static int Method1()  
  2.         {  
  3.             try  
  4.             {  
  5.                 return Method1_1();  
  6.             }  
  7.             catch (Exception ex)  
  8.             {  
  9.                 Console.WriteLine(ex.Message);  
  10.                 throw;  
  11.             }  
  12.         }  

會發生什么?

注意:這次沒有throw ex, 而是 throw.

我們發現StackTrace又不會丟了:

   at ExceptionMethodCall.Program.Method1_1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 40
   at ExceptionMethodCall.Program.Method1() in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 29
   at ExceptionMethodCall.Program.Main(String[] args) in c:\Projects\ExceptionMethodCall\ExceptionMethodCall\Program.cs:line 16

原因是什么?

 

我就隨便說說我的想法, 你這么想也行 不這么想也行, 但是我不負責哦:

catch(Exception ex) 會實例化一個Exception 對象,其實就是在此處你catch到的這個Exception。你怎么處理它都可以, 寫log或者Print出來,

但是你就是不要throw 它。 你throw它了,exception stack就被清空。沒有throw 它, exception stack里就始終保存所有exceptions。

 

在更多:

如果Method1這么寫:

[csharp]  view plain  copy
 
 print?
  1. public static int Method1()  
  2.         {  
  3.            return Method1_1();  
  4.         }  

注意:沒有寫任何try.. catch. 可能有人覺得會丟StackTrace, 事實上不會. 這里Method1() call Method1_1(), 它會完整的保存StackTrace。

事實上,你寫更多層都沒有關系, StackTrace依然很完整。

 

所以綜上所述:

1. 如非必要, 不要給方法加任何try.. catch.., 只在調用方法的最外層處理Exception;

2. 如果需要在方法里處理Exception, 你直接catch(Exception ex)處理就好了, 不要throw ex;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM