在MSDN中,对Thread.Abort()方法的描述为:“调用此方法 通常会终止线程。”
为什么不总是?
在什么情况下它不会终止线程?
还有其他终止线程的可能性吗?
Answers:
Thread.Abort()
ThreadAbortException
在线程上注入a 。线程可以通过调用取消请求Thread.ResetAbort()
。此外,还有某些代码部分,例如finally
将在处理异常之前执行的块。如果由于某种原因线程被卡在这样的块中,则永远不会在线程上引发异常。
由于调用者在调用时几乎无法控制线程的状态Abort()
,因此通常不建议这样做。将消息传递给请求终止的线程。
在什么情况下它不会终止线程?
这个问题是重复的。
还有其他终止线程的可能性吗?
是。您的问题是,您永远不要启动无法礼貌地告知要停止的线程,并且该线程会及时停止。如果您必须启动一个线程,该线程可能会(1)难以停止,(2)越野车或最糟糕的(3)对用户不利的线程,那么正确的做法是使一个新进程,在新进程中启动线程,然后在您希望线程中断时终止该进程。唯一可以确保安全终止不合作的线程的事情是操作系统,将其整个过程都销毁了。
有关更多详细信息,请参见我对这个问题的回答过长:
最后一点是相关的,在这里我讨论了在中止线程之前应该等待多长时间杀死线程自己的注意事项。
为什么不总是?在什么情况下它不终止线程?
对于初学者来说,线程可能会捕捉到ThreadAbortException
并取消其自身的终止。否则,它可能会导致您尝试中止计算所需的时间。因此,运行时无法保证在您请求线程之后线程将始终终止。
ThreadAbortException
有更多:
调用Abort方法销毁线程时,公共语言运行库将引发ThreadAbortException。ThreadAbortException是可以捕获的特殊异常,但是它将在catch块的末尾自动再次引发。引发此异常时,运行时将在结束线程之前执行所有的finally块。由于线程可以在finally块中进行无限制的计算,或调用
Thread.ResetAbort()
取消中止,因此无法保证线程将永远结束。
您不需要Abort()
手动创建线程。如果您只是让线程中的方法返回,那么CLR将为您完成所有的工作。这将正常结束线程。
我似乎无法中止陷入循环的线程:
//immortal
Thread th1 = new Thread(() => { while (true) {}});
但是,如果在循环过程中处于睡眠状态,我可以中止线程:
//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
ThreadAborts不会在finally块内或BeginCriticalRegion和EndCriticalRegion之间发生
OT:有关并发性的全面,不可知论的语言,可疑的有用性和令人毛骨悚然的并发性,请参见Verity Stob!
我曾经遇到过线程太忙而无法听到Abort()调用的情况,这通常会导致ThreadAbortingException被抛出到我的代码中。