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

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

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

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

Thread.Abort只应该被使用,甚至可能不会,在线程正在运行的app域被拆除的情况下,最好只在进程被终止时才使用。

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

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

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

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

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

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

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

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

有关如何很好地执行此操作的示例,请参阅我关于优雅线程终止的文章 。

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

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

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

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

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