【问题标题】:How to detect if a program is executing under a thrown exception at runtime?如何检测程序是否在运行时抛出的异常下执行?
【发布时间】:2010-08-23 21:31:38
【问题描述】:

我可以在运行时在方法 Helper() 中检测到程序执行是抛出异常的结果吗?

注意,我的目标是避免扩展方法 Helper() 以将异常对象作为输入参数。

public void MyFunc1()
{
  try
  {
    // some code here that eventaully throws an exception
  }
  catch( Exception ex )
  {
     Helper();
  }
}

public void MyFunc2()
{
   Helper();
}

private void Helper()
{
    // how can I check if program execution is the  
    // result of a thrown exception here.
}

【问题讨论】:

    标签: c# .net exception


    【解决方案1】:

    有一个涉及Marshal.GetExceptionPointersMarshal.GetExceptionCode 的可怕黑客攻击并非适用于所有平台:

    public static Boolean IsInException()
    {
       return Marshal.GetExceptionPointers() != IntPtr.Zero ||
              Marshal.GetExceptionCode() != 0;
    }
    

    从此页面:http://www.codewrecks.com/blog/index.php/2008/07/25/detecting-if-finally-block-is-executing-for-an-manhandled-exception/

    【讨论】:

    • +1/2 表示疯狂的解决方案,+1/2 表示这是一个可怕的黑客攻击
    • 这仅适用于以 Windows SEH 异常开始的异常。像 NullReference 或 AccessViolation。
    • 感谢汉斯的精确。感谢西蒙的半分。我认为还有另一个涉及检查堆栈帧的“更清洁”黑客,但我需要睡觉,我会再试一次:-)。
    • 谢谢,根据我提出的问题,这是最正确的答案。
    • @HansPassant:对于我来说,使用普通的 throw new Exception() 效果很好。也许这已经改变了?
    【解决方案2】:

    我想不出你为什么不这样做:

    private void Helper(bool exceptionWasCaught)
    {
        //...
    }
    

    【讨论】:

    • 在一个完美的世界里我同意;但是,我的示例简化了我的情况,我试图避免更改 Helper 方法的签名。
    • StackFrame 类:不。无法确定是否正在处理异常。全局变量。
    • 谢谢,我同意你的回答,当我在代码中深入几层并且我不想更改方法签名时,我就想到了我的问题。最后我决定根据我得到的答案更改签名。
    【解决方案3】:

    我不知道。这很麻烦,但它完全将您描述为开发人员的意图:

    private bool inException = false;
    
    public void MyFunc1()
    {
      try
      {
        inException = false;
    
        // some code here that eventaully throws an exception
      }
      catch( Exception ex )
      {
         inException = true;
         Helper();
      }
    }
    
    public void MyFunc2()
    {
       inException = false;
       Helper();
    }
    
    private void Helper()
    {
        // how can I check if program execution is the  
        // result of a thrown exception here.
        if (inException)
        {
            // do things.
        }
    }
    

    【讨论】:

    • 抱歉,这是非常糟糕的设计,我绝不会建议这样的代码!请人们不要使用此代码!采用“Hans Passant”版本或更好地传递异常而不是布尔值。
    • 在一个完美的世界里我同意;但是,我的示例简化了我的情况,我试图避免更改 Helper 方法的签名。 – Zamboni 2 分钟前
    • @Scordo:我特意说它不是那么好。很多时候,人们继承的代码不能像那样轻易地改变方法的签名。毫无疑问,我同意汉斯的方式。如果您可以展示一个对方法签名具有最小侵入性且更清洁的解决方案,请贡献。
    • @Zamboni:我不会更改方法签名。事实上,根据您对汉斯的评论,我确实不是
    • +1 仅仅是因为这只是在不修改Helper 签名的情况下回答原始问题的唯一方法。是的,这很可怕,但这只是因为这个问题已经很可怕了(为了抓住Exception)。
    【解决方案4】:

    我认为你想多了。如果您有异常,请传递异常。如果你不这样做,就不要。

    为什么不想更改 Helper() 方法的签名?

    public void MyFunc1()
    {
      try
      {
        // some code here that eventually throws an exception
      }
      catch( Exception ex )
      {
         Helper(ex);
      }
    }
    
    private void Helper(Exception ex = null)
    {
        // result of a thrown exception here.
        if (ex!=null)
        {
            // do things.
        } else {
            // do other things
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 2010-12-04
      相关资源
      最近更新 更多