C#Thread Termination和Thread.Abort()

时间:2010-02-12 13:14:28

标签: c# .net multithreading

在MSDN中,Thread.Abort()方法的描述说:“调用此方法通常终止线程。”

为什么不总是?

在哪些情况下它不会终止线程?

还有其他可能终止线程吗?

10 个答案:

答案 0 :(得分:57)

Thread.Abort()在线程上注入ThreadAbortException。线程可以通过调用Thread.ResetAbort()来取消请求。此外,还有某些代码部分,例如在处理异常之前将执行的finally块。如果由于某种原因线程卡在这样的块中,则线程上永远不会引发异常。

由于调用者在调用Abort()时几乎无法控制线程的状态,因此通常不建议这样做。将消息传递给请求终止的线程。

答案 1 :(得分:51)

  

在哪些情况下它不会终止线程?

这个问题是重复的。

What's wrong with using Thread.Abort()

  

是否有任何其他可能性来终止线程?

是。你的问题是,你永远不应该启动一个你不能礼貌地停止的线程,它会及时停止。如果你处于这样一种情况,你必须启动一个可能(1)难以停止的线程,(2)越野车,或者最糟糕的(3)对用户不利,那么正确的做法是制作一个新进程,在新进程中启动线程,然后在希望线程关闭时终止进程。唯一可以保证不合作线程安全终止的是操作系统整个过程。

有关详细信息,请参阅我对此问题的过长答案:

Using lock statement within a loop in C#

相关位是最后一位,我讨论了关于在中止线程之前等待线程自杀多长时间的考虑因素。

答案 2 :(得分:17)

  

为什么不总是?   在哪些情况下它不会终止线程?

首先,线程可能会捕获ThreadAbortException并取消自己的终止。或者它可以在您尝试中止时执行永远需要的计算。因此,运行时无法保证线程在您要求后始终终止。

ThreadAbortException 有更多:

  

当调用Abort方法来销毁线程时,公共语言运行库会抛出ThreadAbortException。 ThreadAbortException是一个可以捕获的特殊异常,但它会在catch块的末尾自动再次引发。引发此异常时,运行时会在结束线程之前执行所有finally块。 由于线程可以在finally块中执行无限制计算,或者调用Thread.ResetAbort()来取消中止,因此无法保证线程将永远结束。

您无需手动Abort()线程。如果您只是让线程中的方法返回,CLR将为您完成所有脏工作;这将正常结束线程。

答案 3 :(得分:6)

FileStream.Read()到当前未收到任何内容的命名管道(在等待传入数据时读取调用块)将不会响应Thread.Abort()。它仍然在Read()电话中。

答案 4 :(得分:5)

如果一个线程持有一个锁并被中止/杀死怎么办?资源仍然存在

  

当线程调用时它工作正常   中止,但不是其他线程。   中止,强行终止   受影响的线程,即使它没有   完成任务并提供否   清理机会   资源

参考MSDN


请参阅:Managed Threading Best Practices

答案 5 :(得分:4)

ThreadAborts不会出现在finally块内或BeginCriticalRegionEndCriticalRegion之间

答案 6 :(得分:4)

我似乎无法中止陷入循环的线程:

//immortal
Thread th1 = new Thread(() => { while (true) {}});

然而,如果在循环期间休眠,我可以中止线程:

//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});

答案 7 :(得分:3)

因为您可以捕获ThreadAbortException并在处理程序内调用Thread.ResetAbort

答案 8 :(得分:0)

OT:对于一个全面的,与语言无关的,有问题且有用的有趣的并发性,请参阅Verity Stob

答案 9 :(得分:-1)

我遇到线程太忙而无法听到Abort()调用的情况,这通常会导致我的代码抛出ThreadAbortingException。