1. キャッチスローのいくつかの形式とパフォーマンスへの影響:
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コード(以下のコードはリリースバージョンの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 がコンパイラによって最適化されていることがわかります。修正された治療法: r IL_0000: ret //即为 return 标记 返回值
E
处 Form1_doubleClick での Try Catch はパフォーマンスに影響します。
と一致しています)。
それでは、デバッグモードのILコードはどのように見えるのでしょうか?
.locals init ([0] class [mscorlib]System.Exception ee) //定义 Exception 类型参数 ee (此时已经把ee存入了Call Stack中)
デバッグ モードでの 4 つの書き込みメソッドの違いは、rethrow と throw の違いのみであることがわかります。イリノイ州で rethrow と throw は何を表しますか?
Throw: 現在計算スタック上にある例外オブジェクトをスローします。
再スロー: 現在の例外を再スローします。つまり、例外をスローすると、CLR は例外の開始点をリセットします。 CLR は、スローされた最新の例外の位置のみを記録します。次のコードは例外をスローし、CLR が例外の開始点をリセットします:
try { } catch { throw; } try { } catch (Exception) { throw; } try { } catch (Exception ee) { throw; }
対照的に、例外オブジェクトをスローした場合、CLR はその例外の開始点をリセットしません。 stack を使用すると、次のコードは例外をスローしますが、CLR が例外の開始点をリセットすることはありません:
.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
C# は throw と throw ex を使用して例外をスローしますが、違いがあります。ふたつの間に。
Throw e は例外を再スローします。これは元の例外を転送しませんが、StackTrace を含む多くの例外の内部情報を変更します。呼び出し接続が非常に深い状況では、パフォーマンスの低下は想像を超えます。
上記は C# 例外処理 (Catch Throw) IL 解析の内容です。その他の関連内容については、PHP 中国語 Web サイト (www.php.cn) をご覧ください。