.NET中线程中止和中断的区别

时间:2009-10-12 17:51:47

标签: c# multithreading

Thraed.Abort()和Thread.Interrupt()之间有什么区别。如何以线程安全方式调用它们。如果提供了简单的示例,那将会很有帮助。

4 个答案:

答案 0 :(得分:25)

首先,这些都不是好的线程同步结构。

首先,Thread.Abort说“我不在乎你在做什么,只是停止这样做,并保留现在的一切”。这基本上就是说“嘿,击败它”的编程方式。如果您的线程打开了文件,那么这些文件将保持打开状态,直到垃圾收集完成对象的完成。

只有在线程正在运行的应用程序域被拆除时才应该使用Thread.Abort,即使这样也可能不被使用,最好只在进程被终止时才使用。

其次,Thread.Interrupt是一个相当奇怪的野兽。它基本上说“我不在乎你在等什么,不再等待它”。这里奇怪的是,如果线程当前没有等待任何东西,那就是“我不关心你接下来要等什么,但是当你这样做时,立即停止等待它。”

这两个迹象表明你将自己的意志强加于一个并非旨在被告知此类事情的线索。

要正确中止线程,线程应定期检查某种标志,无论是简单易变的布尔变量还是事件对象。如果标志显示“你现在应该终止”,那么线程应该通过以有序的方式返回方法来终止。

要正确唤醒线程,线程应该在必须等待同步对象的位置包含一个“请停止等待”的对象,它也会等待。因此,基本上它会对所需的对象发出信号,或者“请停止等待”对象变为信号,确定哪一个做了,做了正确的事。

因此,您应该使用普通的同步对象(如事件,互斥体,信号量等)来编写线程,而不是Thread.Abort和Thread.Interrupt。

出于同样的原因,Thread.SuspendThread.Resume应该保持不变,并且它们在.NET的更高版本中也已经过时了。

答案 1 :(得分:10)

除非你在当前正在执行的线程上调用AbortInterrupt(例如,ASP.NET会突然终止请求)你基本上不能以线程安全的方式调用它们。

使用WaitHandleMonitor.Wait / Pulse以可唤醒的方式等待。如果你正在拆除应用程序,你应该只删除其他线程 - 基本上 - 否则你可能最终处于未知状态。

请参阅my article on graceful thread termination以获取如何很好地完成此操作的示例。

答案 2 :(得分:2)

Thread.Abort()在目标线程上引发ThreadAbortException。通常强制线程终止。建议不要停止线程的处理。

Thread.Interrupt()中断处于WaitSleepJoin状态的线程 - 基本上阻塞像WaitHandle这样的资源。这允许调用者解除对线程的阻塞。

两者都不是“线程安全的” - 在某种意义上它们是专门用于以难以预测的方式影响线程的行为。

通常建议使用同步对象(如WaitHandles或Semaphores)来允许线程安全地彼此同步。

答案 3 :(得分:1)

Abort和Interrupt之间的区别在于,虽然它们都会抛出异常(ThreadAbortException和ThreadInterruptException),但调用Abort会在catch块结束时重新抛出异常,并确保结束正在运行的线程。