C#異常處理的方式

來源:互聯網
上載者:User

 

C#異常處理的方式

 

c#中所有可以被拋出的異常都是直接或間接繼承自System.Exception類

 

支援的捕獲異常的語句塊如下:

try … catch

try … catch … finally

try… finally

 

c#代碼塊中產生異常堆棧資訊的時機不是在throw語句執行的地方,而是在第一次捕獲的地方

 

以上三種方式中 try ... finally一定不會影響堆棧資訊

可能會影響的地方主要集中在catch塊中

 

catch子句聲明方式又有以下幾種

 

catch{}

catch(Exception){}

catch(Exception ex){}

 

這三種寫法從捕獲異常的能力上來說基本上是等效

第三種方式只是讓編寫代碼的人可以使用異常參數,如果不使用異常參數的話可以用前面兩種,第二種只是更加明確的指出了捕獲的是Exception或者是從Exception繼承的異常

 

catch塊內可以再次拋出異常,拋出時可以支援下面幾種方式

 

throw;

throw ex; // ex來自於catch(Exception ex)

throw new SomeException();

 

後面兩種情況是一樣的, stack trace認為你catch到的異常已經被處理了,只不過處理過程中又拋出新的異常,這時候stack trace就把throw 後的那個異常執行個體當作錯誤根源了。之前的堆棧資訊全部會清除掉

第一種方式網上和MSDN上都說可以保留堆棧資訊。經測試發現不全是如此:

在Debug版本下,產生的程式碼在執行沒有任何最佳化,直接使用throw;這種方式的確是能保留堆棧資訊。這個時候的堆棧資訊就好像是在try塊內部異常產生的地方就記錄好了一樣。

在Release下,輸出的資訊中只包含了從捕獲位置開始向上的堆棧資訊。即從異常源發生位置到第一次catch塊捕獲發生之間的堆棧資訊都不存在了

 

總結如下:

以前的異常資訊中有出錯的點很容易就找到了,那是因為正巧異常源與第一次捕獲的地方很接近

否則的話越是在調用的最上層捕獲到異常,越不容易找到異常源在什麼位置(這裡都是在Release條件下)

在Release版本下,異常越早捕獲,越能精確定位出錯位置,越晚捕獲,從堆棧中獲得的獲得的有效資訊也越少,即使是用了throw;這樣的方式也一樣

嚴格禁止 下面這種寫法:

try{

         // do

}

catch(Exception ex)

{

throw ex;

}

如有必要需改用 throw; 或者 throw new SomeException(msg, ex); 這樣的形式

 

如果是捕獲了異常不想再次拋出(一般用在捕獲到的異常在預期範圍內,已經有相應的處理方式了),最好是能記錄日誌,表示發生過異常

 

 

附上一個測試:

Release 使用throw;

Release 使用throw ex;

 

 

Release下更極端的例子去掉了除最外層外所有的try…catch

 

 

 

Debug 使用throw;

 

 

Debug 使用throw ex;

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.