C#线程终止和Thread.Abort()
在MSDN中,Thread.Abort()方法的描述表示:“调用此方法通常会终止该线程。
为什么不总是?
在哪种情况下,它不会终止线程?
有没有其他的可能性来终止线程?
Thread.Abort()
在线程上注入ThreadAbortException
。 线程可以通过调用Thread.ResetAbort()
来取消请求。 另外,还有一些代码部分,比如在处理exception之前会执行的finally
块。 如果由于某种原因,线程卡在这样的块中,则线程上将永远不会产生exception。
由于调用者在调用Abort()
时几乎不能控制线程的状态,通常不build议这样做。 将消息传递给请求终止的线程。
在哪种情况下,它不会终止线程?
这个问题是重复的。
使用Thread.Abort()有什么问题
还有其他的可能性来终止线程吗?
是。 你的问题是,你永远不应该启动一个你不能礼貌地停下来的线程,而是及时停下来。 如果您处于一种可能(1)难以阻止的线程,(2)越野车,或者最糟糕的(3)敌视使用者的情况,那么正确的做法是使一个新的进程,在新进程中启动线程,然后在线程closures时终止进程 。 唯一能够保证安全终止不合作的线程的是操作系统将其整个过程取消。
有关更多详细信息,请参阅我对此问题的过长答案:
在C#中循环中使用locking语句
相关的位是最后一点,我讨论了什么是你应该等待一个线程在中止之前自杀的考虑因素。
为什么不总是? 在哪种情况下,它不会导致线程?
对于初学者来说,一个线程可能会捕获一个ThreadAbortException
并取消它自己的终止。 或者,它可以执行一个计算,而你试图放弃它,直到永远。 因此,运行时无法保证线程在您提出请求后总是会终止。
ThreadAbortException
有更多的:
当调用Abort方法销毁一个线程时,公共语言运行库会抛出一个ThreadAbortExceptionexception。 ThreadAbortException是一个特殊的exception,可以被捕获,但是它会在catch块的末尾自动重新引发。 当引发这个exception时,运行时会在结束线程之前执行所有的finally块。 由于线程可以在finally块中执行无限计算,或者调用
Thread.ResetAbort()
来取消中止,所以不能保证线程永远不会结束。
您不需要手动Abort()
线程。 如果你只是简单地让线程中的方法返回,CLR将为你做所有的肮脏的工作; 这将正常结束线程。
FileStream.read
到当前没有接收任何东西的命名pipe道(在等待传入数据时读取调用块)将不会响应Thread.Abort
。 它仍然在read()
。
如果一个线程持有一个锁并被中止/终止,该怎么办? 资源仍然卡住
当一个线程调用中止本身而不是其他线程时它工作正常。 中止,强行终止受影响的线程,即使它没有完成任务,也不提供资源清理的机会
参考MSDN
请参阅: 托pipe线程最佳实践
ThreadAborts不会在finally块或BeginCriticalRegion和EndCriticalRegion之间发生
因为你可以捕获ThreadAbortException
并在处理程序中调用Thread.ResetAbort
。
我似乎无法中止一个循环卡住的线程:
//immortal Thread th1 = new Thread(() => { while (true) {}});
我可以中止线程,如果在循环中睡觉:
//mortal Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
OT:对于一个全面的,语言不可知的,可疑的有用和有趣的并发性请参见Verity Stob !
我遇到过这样的情况:线程太忙,无法听到Abort()调用,这通常会导致ThreadAbortingException抛出我的代码。