C# 異常處理(Catch Throw)IL分析

來源:互聯網
上載者:User
1、catch throw的幾種形式及效能影響:

 private void Form1_Click(object sender, EventArgs e)        {            try            {            }            catch            {                throw;            }        }        private void Form1_Load(object sender, EventArgs e)        {            try            {            }            catch (Exception)            {                throw;            }        }        private void Form1_Enter(object sender, EventArgs e)        {            try            {            }            catch (Exception ee)            {                throw;            }        }        private void Form1_DoubleClick(object sender, EventArgs e)        {            try            {            }            catch (Exception ee)            {                throw ee;            }        }

對應的IL代碼(以下代碼是release版本的IL代碼):

.method private hidebysig instance void  Form1_Click(object sender,                                                     class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       1 (0x1)  .maxstack  8  IL_0000:  ret} // end of method Form1::Form1_Click.method private hidebysig instance void  Form1_Load(object sender,                                                    class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       1 (0x1)  .maxstack  8  IL_0000:  ret} // end of method Form1::Form1_Load.method private hidebysig instance void  Form1_Enter(object sender,                                                     class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       1 (0x1)  .maxstack  8  IL_0000:  ret} // end of method Form1::Form1_Enter.method private hidebysig instance void  Form1_DoubleClick(object sender,                                                           class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       1 (0x1)  .maxstack  1  .locals init ([0] class [mscorlib]System.Exception ee)  IL_0000:  ret} // end of method Form1::Form1_DoubleClick

可以看到Form1_Click、Form1_Load、Form1_Enter中的try catch已經被編譯器最佳化掉了:


IL_0000:  ret         //即為  return  標記 傳回值


只有Form1_DoubleClick中的try catch中對try catch進行了處理:

 .locals init ([0] class [mscorlib]System.Exception ee) //定義 Exception 型別參數 ee (此時已經把ee存入了Call Stack中)

即在Form1_DoubleClick中的try catch才會對效能產生影響。

==》可以看出一下三種try catch的寫法對於release版本的代碼來說是完全一樣,也不會產生任何的效能消耗:

           try            {            }            catch            {                throw;            }            try            {            }            catch (Exception)            {                throw;            }            try            {            }            catch (Exception ee)            {                throw;            }

對於上面的結論大家可以寫測試demo驗證一下 (已測試,結果與分析一致)。


那麼對於debug模式下的IL代碼是什麼樣子的呢?

.method private hidebysig instance void  Form1_Click(object sender,                                                     class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       11 (0xb)  .maxstack  1  IL_0000:  nop  .try  {    IL_0001:  nop    IL_0002:  nop    IL_0003:  leave.s    IL_0009  }  // end .try  catch [mscorlib]System.Object   {    IL_0005:  pop    IL_0006:  nop    IL_0007:  rethrow  }  // end handler  IL_0009:  nop  IL_000a:  ret} // end of method Form1::Form1_Click.method private hidebysig instance void  Form1_Load(object sender,                                                    class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       11 (0xb)  .maxstack  1  IL_0000:  nop  .try  {    IL_0001:  nop    IL_0002:  nop    IL_0003:  leave.s    IL_0009  }  // end .try  catch [mscorlib]System.Exception   {    IL_0005:  pop    IL_0006:  nop    IL_0007:  rethrow  }  // end handler  IL_0009:  nop  IL_000a:  ret} // end of method Form1::Form1_Load.method private hidebysig instance void  Form1_Enter(object sender,                                                     class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       11 (0xb)  .maxstack  1  .locals init ([0] class [mscorlib]System.Exception ee)  IL_0000:  nop  .try  {    IL_0001:  nop    IL_0002:  nop    IL_0003:  leave.s    IL_0009  }  // end .try  catch [mscorlib]System.Exception   {    IL_0005:  stloc.0    IL_0006:  nop    IL_0007:  rethrow  }  // end handler  IL_0009:  nop  IL_000a:  ret} // end of method Form1::Form1_Enter.method private hidebysig instance void  Form1_DoubleClick(object sender,                                                           class [mscorlib]System.EventArgs e) cil managed{  // 代碼大小       11 (0xb)  .maxstack  1  .locals init ([0] class [mscorlib]System.Exception ee)  IL_0000:  nop  .try  {    IL_0001:  nop    IL_0002:  nop    IL_0003:  leave.s    IL_0009  }  // end .try  catch [mscorlib]System.Exception   {    IL_0005:  stloc.0    IL_0006:  nop    IL_0007:  ldloc.0    IL_0008:  throw  }  // end handler  IL_0009:  nop  IL_000a:  ret} // end of method Form1::Form1_DoubleClick

可以看出四種寫法在debug模式下區別只是:rethrow與throw的區別。IL中rethrow與throw分別代表啥呢?


Throw:引發當前位於計算堆棧上的異常對象。
Rethrow:再次引發當前異常。

即當我們拋出一個異常時, CLR會重新設定一個異常起始點。 CLR只記錄最近一次異常拋出的位置。下面代碼拋出一個異常,從而導致CLR重新設定該異常的起始點:

            try            {                //一些處理            }            catch (Exception e)            {                //一些處理                throw e;   //CLR認為這裡是異常的起始點            }

相反,如果我們拋出一個異常對象, CLR將不會重新設定其堆棧的起始點,下面代碼拋出一個異常,但不會導致CLR重新設定異常的起始點:

           try            {                //一些處理            }            catch (Exception e)            {                //一些處理                throw;  //CLR不會重新設定異常的起始點            }

C#中使用throw和throw ex拋出異常,但二者是有區別的。

在C#中推薦使用throw;來拋出異常;throw ex;會將到現在為止的所有資訊清空,認為你catch到的異常已經被處理了,只不過處理過程中又拋出新的異常,從而找不到真正的錯誤源。

throw e重新拋出異常,並非轉寄原來的異常,而會更改包括StackTrace在內的許多異常內部資訊;對於調用連很深情況,效能損耗超出想象。

以上就是C# 異常處理(Catch Throw)IL分析的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!


  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.