ThreadAbortException仍然强制执行finally(try/catch)部分中的代码吗?

6

我有一个 System.Timers.Timer 定时器,它的 AutoReset 属性设置为 false。我使用 try/finally 确保在其 callback 结束时启动定时器(我以这种方式使用定时器来防止 callback 执行重叠)。代码:

// inside timer call back
try
{
    // Do something
}
finally
{
    timer.Start(); // Is this line always executed?
}

我的问题是,如果执行线程被中止finally部分是否仍然会执行,还是没有线程来运行那部分?


顺便提一下,如果你在计时器回调中,那么你就在线程池线程上 - 而线程池线程永远不会被中止。 - Luaan
5个回答

7

官方资料显示...

当调用Abort方法销毁线程时,公共语言运行时会抛出ThreadAbortException。ThreadAbortException是一种特殊的异常,可以被捕获,但它会在catch块结束时自动再次引发。当引发此异常时,运行时在结束线程之前执行所有finally块。由于线程可以在finally块中执行无限计算或调用Thread.ResetAbort来取消中止,因此无法保证线程将在任何时候结束。如果您想等待已中止的线程结束,可以调用Thread.Join方法。Join是一个阻塞调用,直到线程实际停止执行才返回。

MSDN上了解更多信息。


4

是的,那行代码总是会被执行,直到finally子句中的代码执行完毕,才会取消中止。


4
文档所述(强调是我的):
当在线程上调用此方法时,系统会抛出ThreadAbortException异常以中止它。 ThreadAbortException是一种特殊的异常,应用程序代码可以捕获它,但除非调用ResetAbort,否则该异常将在catch块结束时重新抛出。 ResetAbort取消中止请求,并防止ThreadAbortException终止线程。未执行的finally块在线程被中止之前执行。
不能保证立即或根本中止线程。如果线程在作为中止过程的一部分调用的finally块中执行无限量的计算,则可能会发生这种情况,从而无限期地延迟中止。要等待线程中止,可以在调用Abort方法后在线程上调用Join方法,但不能保证等待会结束。
因此答案是是的,finally块将被执行。

1

是的,无论从try中如何退出,finally都将被使用。

而catch用于处理语句块中发生的异常,
finally用于确保代码语句块执行,无论前面的try块如何退出。

MSDN上阅读更多内容。


1
如果线程已经被中止,catch块和finally块仍然可以继续执行。
请参考此链接以了解系统.threading类如何处理它: 深入了解ThreadAbortException

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接