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

2021-09-23 20:04:34 字數 3683 閱讀 8791

1、catch throw的幾種形式及效能影響:

private void form1_click(object sender, eventargs e)

catch

}private void form1_load(object sender, eventargs e)

catch (exception)

}private void form1_enter(object sender, eventargs e)

catch (exception ee)

}private void form1_doubleclick(object sender, eventargs e)

catch (exception ee)

}

對應的il**(以下**是release版本的il**):

.method private hidebysig instance void  form1_click(object sender,

class [mscorlib]system.eventargs e) cil managed

// end of method form1::form1_click

.method private hidebysig instance void form1_load(object sender,

class [mscorlib]system.eventargs e) cil managed

// end of method form1::form1_load

.method private hidebysig instance void form1_enter(object sender,

class [mscorlib]system.eventargs e) cil managed

// end of method form1::form1_enter

.method private hidebysig instance void form1_doubleclick(object sender,

class [mscorlib]system.eventargs e) cil managed

// 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

trycatch (exception)

trycatch (exception ee)

對於上面的結論大家可以寫測試demo驗證一下 (已測試,結果與分析一致那麼對於debug模式下的il**是什麼樣子的呢?

.method private hidebysig instance void  form1_click(object sender,

class [mscorlib]system.eventargs e) cil managed

// end .try

catch [mscorlib]system.object

// 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

// end .try

catch [mscorlib]system.exception

// 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

// end .try

catch [mscorlib]system.exception

// 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

// end .try

catch [mscorlib]system.exception

// 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)

相反,如果我們丟擲乙個異常物件, clr將不會重新設定其堆疊的起始點,下面**丟擲乙個異常,但不會導致clr重新設定異常的起始點:

try

catch (exception e)

c#中使用throw和throw ex丟擲異常,但二者是有區別的。

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

throw e重新丟擲異常,並非**原來的異常,而會更改包括stacktrace在內的許多異常內部資訊;對於呼叫連很深情況,效能損耗超出想象。

拓展閱讀:

il指令詳細

.net中異常處理的最佳實踐(譯)

C 異常處理

結構化異常 structured exception vs c 異常 c exception 大家都知道c 異常是c 語言的乙個特性,使用者可以使用throw的方式來丟擲異常,try catch 來捕獲異常。結構化異常是諸如,zero divided,access violations等異常,這些異...

c 異常處理

一 概述 c 自身有著非常強的糾錯能力,發展到如今,已經建立了比較完善的異常處理機制。c 的異常情況無非兩種,一種是語法錯誤,即程式中出現了錯誤的語句,函式,結構和類,致使編譯程式無法進行。另一種是執行時發生的錯誤,一般與演算法有關。關於語法錯誤,不必多說,寫 時心細一點就可以解決。c 編譯器的報錯...

C 異常處理

程式設計師常常忽視異常處理的重要性,這給他們自己的 造成相當大損害。本文將討論如何在c 中使用異常處理,並介紹在應用 中新增 片段以防止某些錯誤的一些簡單方法,這些錯誤可能導致程式異常終止。結構化異常處理 net框架提供一種標準的錯誤報告機制稱為結構化異常處理。這種機制依賴於應用中報告錯誤的異常。在...