如何确定是否正在处理.NET异常?

Rom*_*kov 15 .net c# exception-handling using-statement

我们正在研究C#中的编码模式,我们希望在其中使用带有特殊类的"using"子句,Dispose()根据"using"主体是正常退出还是异常退出,其方法会有不同的含义.

据我所知,CLR会跟踪当前正在处理的异常,直到它被"catch"处理程序占用为止.但是,这些信息是否以任何方式公开以供代码访问并不完全清楚.你知道它是否,如果是,如何访问它?

例如:

using (var x = new MyObject())
{
    x.DoSomething();
    x.DoMoreThings();
}

class MyObject : IDisposable
{
    public void Dispose()
    {
        if (ExceptionIsBeingHandled)
            Rollback();
        else
            Commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

这几乎看起来像System.Transactions.TransactionScope,除了成功/失败不是通过调用确定x.Complete(),而是基于using身体是否正常退出.

Vol*_*erK 12

http://www.codewrecks.com/blog/index.php/2008/07/25/detecting-if-finally-block-is-executing-for-an-manhandled-exception/描述了一个"hack"来检测是否您的代码是否在异常处理模式下执行.它使用Marshal.GetExceptionPointers来查看异常是否"活动".

但请记住:

备注

仅为编译器支持结构化异常处理(SEH)公开GetExceptionPointers.NoteNote:

此方法使用SecurityAction.LinkDemand来防止从不受信任的代码调用它; 只有直接调用者才需要具有SecurityPermissionAttribute.UnmanagedCode权限.如果可以从部分受信任的代码调用代码,则不要在没有验证的情况下将用户输入传递给Marshal类方法.有关使用LinkDemand成员的重要限制,请参阅Demand vs. LinkDemand.

  • 这可能是你问题的唯一实际答案,但这似乎是一个非常糟糕的想法. (5认同)
  • 如果您沿着这条路走下去,请先查看以下博客:http://geekswithblogs.net/akraus1/archive/2008/04/08/121121.aspx (2认同)
  • romkyns:有了这种黑客攻击,你不会在小型测试项目中看到重大问题.当您的代码部署到具有1000个独特且不同的配置怪癖的计算机时,您将看到问题. (2认同)

Rom*_*kov 7

这个问题不是答案,而只是说明我从未在实际代码中使用"接受"的黑客攻击,所以它仍然在很大程度上未经测试"在野外".相反,我们去了这样的事情:

DoThings(x =>
{
    x.DoSomething();
    x.DoMoreThings();
});
Run Code Online (Sandbox Code Playgroud)

哪里

public void DoThings(Action<MyObject> action)
{
    bool success = false;
    try
    {
        action(new MyObject());
        Commit();
        success = true;
    }
    finally
    {
        if (!success)
            Rollback();
    }
}
Run Code Online (Sandbox Code Playgroud)

关键点在于它与问题中的"使用"示例一样紧凑,并且不使用任何黑客.

其中的缺点是性能损失(在我们的情况下完全可以忽略不计),而F10 DoThings在我真正希望它直接进入时会踩到x.DoSomething().两者都很小.

  • 由于IntelliSense与匿名方法有关,因此VS2010的吸引力要小得多...... https://connect.microsoft.com/VisualStudio/feedback/details/557224/intellisense-completely-fails-for-collection-inside-anonymous - 方法?WA = wsignin1.0 (3认同)