7

現在実行中のコードが catch ブロック内から呼び出されていることを検出するにはどうすればよいですか?

void SomeFunction()
{
    // how do I detect whether I am being called from within a catch block?
}

編集:

質問者のために、私はこのようなクラスを実装したかったのですが、エラーのバブリング ロジックは気にしません。とにかくそれは私の考えをちょっと破壊します。

public class ErrorManager {

    public void OnException(Exception ex) {
        LogException(ex);
        if (IsInsideCatchBlockAlready()) {
            // don't destroy the stack trace, 
            // but do make sure the error gets bubbled up
            // through the hierarchy of components
            throw; 
        } else {
            // throw the error to make it bubble up 
            // through the hierarchy of components
            throw ex; 
        }
    }

    void LogException(Exception ex) {
        // Log the exception
    }

    bool IsInsideCatchBlockAlready() {
        // How do I implement this?
    }
}
4

6 に答える 6

2

いいえ、それを行う方法はありません。

生成された (IL) コードを分析するという卑劣な方法があるかもしれませんが、それは望ましくないと確信しています。

これは、例外をキャッチする標準のコンソール アプリケーションからの IL です。

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       34 (0x22)
  .maxstack  1
  IL_0000:  nop
  .try
  {
    IL_0001:  nop
    IL_0002:  ldstr      "OK"
    IL_0007:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000c:  nop
    IL_000d:  nop
    IL_000e:  leave.s    IL_0020
  }  // end .try
  catch [mscorlib]System.Exception 
  {
    IL_0010:  pop
    IL_0011:  nop
    IL_0012:  ldstr      "Err"
    IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_001c:  nop
    IL_001d:  nop
    IL_001e:  leave.s    IL_0020
  }  // end handler
  IL_0020:  nop
  IL_0021:  ret
} // end of method Program::Main

現在のコード ( にあるとします) がそのブロック内にあることを分析できれば"OK"、ブロックを抽出できtry ... catchます。もちろん、これは他のメソッドの呼び出しを考慮していません。

それはまた、あなたが抱えている問題に対するばかげた解決策のようにも聞こえるので、望まないことに身を投じる前に、本当にこれをやりたいかどうかをよく考えてください.

于 2014-08-26T14:18:59.643 に答える
1

WindowsでのCLR 例外は、単なる SEH の 1 つです。古典を読んでください: Win32™ 構造化例外処理の深さに関する集中講座。検出する必要があるため、SEH ハンドラー中にコードが実行されていることを検出することは明らかに可能ExceptionNestedExceptionです。あなたがOSまたはデバッガであり、それを解釈する方法を知っていれば、TEBには必要なものがすべて含まれています

あなたのために、私はバックオフして文書化された道をたどることを強くお勧めします. 必要に応じて、ロギングを try/catch ブロックでラップして、スローしないようにする必要があるコードから例外がリークしないようにします。非常に特殊なThreadAbortExceptionため、適切に処理してください。適切なロギングとエラー報告を使用して、 、および/またはにフックします。Application.UnhandledExceptionApplication.ThreadExceptionAppDomain.UnhandledException

于 2014-08-26T14:44:53.597 に答える
0

あなたはいつでも簡単な方法でそれを行うことができます:

void SomeFunction(bool isCalledFromCatch)
{
    // how do I detect whether I am being called from within a catch block?
}

try
{
}
catch(...)
{
    SomeFunction(true);
}
于 2014-08-26T15:05:32.407 に答える
0

他の回答で述べたように、できません。メソッドにパラメーターを渡すことで偽装できますが、それはコードの匂いのようです。

于 2014-08-26T14:33:09.197 に答える