在MSDN中,Thread.Abort()方法的描述说:“调用此方法通常终止线程。”
为什么不总是?
在哪些情况下它不会终止线程?
还有其他可能终止线程吗?
答案 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)
答案 5 :(得分:4)
ThreadAborts不会出现在finally块内或BeginCriticalRegion和EndCriticalRegion之间
答案 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。