保存ナStackTrace/LineNumbersます。純例外
-
22-09-2019 - |
質問
理解の違い 投ex や 投げ, の原StackTrace保存この例:
static void Main(string[] args)
{
try
{
LongFaultyMethod();
}
catch (System.Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
static void LongFaultyMethod()
{
try
{
int x = 20;
SomethingThatThrowsException(x);
}
catch (Exception)
{
throw;
}
}
static void SomethingThatThrowsException(int x)
{
int y = x / (x - x);
}
がないこと。
static void Main(string[] args)
{
try
{
LongFaultyMethod();
}
catch (System.Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
static void LongFaultyMethod()
{
try
{
int x = 20;
int y = x / (x - 20);
}
catch (Exception)
{
throw;
}
}
次のシナリオは同一として出力 投ex かな
両方の場合、期待の行番号yは初期化されます。
解決
私は、この制限は、C#言語、CLI、またはこれらのマイクロソフトの実装内にあるかどうかわからないんだけど、あなたの第二の例は、以下の記事に記載されているようにException.InternalPreserveStackTrace
への明示的な呼び出しが必要な場合です。この方法はinternal
あるので、一般的に反射を介して呼び出さなければなりません。この回答の最後に示したように、このに関わるパフォーマンスの問題はほぼ完全に、通話のためのAction<Exception>
を作成することによって軽減することができます。
参考:<のhref = "http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx" REL =「noreferrer」>例外を再スローし、完全なコールスタックトレースする
を維持の編集のECMA-335パーティションI§12.4.2(例外処理)とパーティションIII§4.24(再スロー)を見直した後、私は今あなたが見ている行動がでセマンティックエラーであると信じていますCLR(CLIのMicrosoftの実装)。行動への唯一の具体的な言及は「rethrow
がオブジェクトにスタックトレースを変更しません。」です場合は、ここで説明し、再スローはPreserveStackTrace
が知っているのCLRの脆弱性の回避策をハックすること、スタックトレースを変更することである。
static void LongFaultyMethod()
{
try
{
int x = 20;
int y = x / (x - 20);
}
catch (Exception ex)
{
PreserveStackTrace(ex); // <-- add this line
throw;
}
}
ここPreserveStackTrace
が、そのブログエントリから1の最適化されます:
private static readonly Action<Exception> _internalPreserveStackTrace =
(Action<Exception>)Delegate.CreateDelegate(
typeof(Action<Exception>),
typeof(Exception).GetMethod(
"InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic));
public static void PreserveStackTrace(Exception e)
{
_internalPreserveStackTrace(e);
}
他のヒント
が、二つ目の例では、rethrowingの例外からと同じ方法です。最初にそれらの異なる方法を私はいかがでしょうか。一つの方法の適用範囲のスタックトレースでなければ見ることができます。
として、最良の方法は常に例外をラップ中に新しい例外です例外です。
"の場合rethrowて行 同一の方法(例外をスタックトレース はひとつだけで行番号情報 りの方法では、ずにスタックトレース この方法は、行番号2 例外がスローされるまで、そして同じ 方法でrethrownから線 数17日までに含まれるのは、昨 行番号から例外が rethrown"
try
{
int x = 20;
int y = x / (x - 20);
}
catch (Exception ex)
{
// do something here.. like log or something
throw new Exception("Internal Exception", ex);
}
私は驚いた多くのコメントは読みくだ!!に書いたコメントすべきなのログについてこの安全に, あさまざまな理由による場合のトップレベルのコードを食べるまで例外と知らない"である場合例外がスローされるまで、ロギングすが交差する例外で!!!
必要がない場合はログインしんでキャッチします。