记录异常时忽略ThreadAbortException

时间:2010-07-19 13:57:57

标签: asp.net exception logging exception-handling

记录异常时忽略ThreadAbortException的正确方法是什么?

只是在一个空的捕获块中捕获它以使其消失是否安全?

4 个答案:

答案 0 :(得分:1)

如果您需要停止ThreadAbortException进一步提升调用堆栈,可以致电Thread.ResetAbort。所以尝试类似的事情:

try
{
  // some code
}
catch (ThreadAbortException ex)
{
  // do some logging
  Thread.ResetAbort();
}

至于“正确” - 这取决于您的使用场景。除非你明白它为何被提出,否则我一般都会对这些问题持谨慎态度。在现在,它是“现在停止,快速,并放弃你正在做的事情”信号。重置它并继续进行进一步处理应该谨慎。

答案 1 :(得分:0)

在一个单独的catch块中捕获它是安全的。作为替代方案,您可以捕获所有异常,然后检查给定的异常e is ThreadAbortException

我因为评论而留下这篇文章。显然,我对这个例外不太了解。

答案 2 :(得分:0)

使用两个catch块:一个用于ThreadAbortException,另一个用于其他块,例如:

void MainLoop()
{   bool workdone;
    try
    {   while( IsWorking ) // cross-thread volatile variable
        {   workdone = Process();
            if( !workdone )
            {   Thread.Sleep( 500 );  }
        }
    }
    catch( ThreadAbortException )
    {   // Forced termination. Exit silently.
    }
    catch (Exception e)
    {   LogError( e );  }
}

答案 3 :(得分:0)

使用更新的.NET版本忽略异常可以简化为

try
{   // ...
}
catch (Exception e) when (!(e is ThreadAbortException))
{   LogError( e );
}

但这可能还不够。 某些库倾向于使用自己的异常包装所有异常。在这种情况下,ThreadAbortExceptiononly可能显示为InnerException。我不会称其为包装ThreadAbortException的最佳实践,但这是现实世界。

要解决这个问题,我建议扩展:

public static bool IsThreadAbort(this Exception ex)
{
    while (ex != null)
    {
        if (ex is ThreadAbortException)
            return true;
        ex = ex.InnerException;
    }
    return false;
}

现在您可以检查:

catch (Exception e) when (!e.IsThreadAbort())
{   LogError( e );
}