记录异常时忽略ThreadAbortException的正确方法是什么?
只是在一个空的捕获块中捕获它以使其消失是否安全?
答案 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 );
}