你们都知道在C#里面,咱们可使用 Thread.Start方法来启动一个线程,当咱们想中止执行的线程时可使用Thread.Abort方法来强制中止正在执行的线程,可是请注意,你肯定调用了Thread.Abort方法后线程就马上中止了吗? 答案是:不是!安全
下面咱们来解释一下Abort方法是如何工做的。由于公用语言运行时管理了全部的托管的线程,一样它能在每一个线程内抛出异常。Abort方法能在目标线程中抛出一个ThreadAbortException异常从而致使目标线程的终止。不过Abort方法被调用后,目标线程可能并非立刻就终止了。由于只要目标线程正在调用非托管的代码并且尚未返回的话,该线程就不会当即终止。而若是目标线程在调用非托管的代码并且陷入了一个死循环的话,该目标线程就根本不会终止。不过这种状况只是一些特例,更多的状况是目标线程在调用托管的代码,一旦Abort被调用那么该线程就当即终止了。spa
其实一个线程在运行时,咱们能够经过Thread.ThreadState属性读出它的状态,正在运行的线程状态就是ThreadState.Running。而后若是咱们想强制中止正在执行的线程,就会调用Thread.Abort方法,可是Thread.Abort方法作的事情只是在线程上抛出了一个ThreadAbortException异常,而后将线程的状态置为ThreadState.AbortRequested,MSDN对AbortRequested状态的解释是:已对线程调用了 Thread.Abort 方法,但线程还没有收到试图终止它的挂起的System.Threading.ThreadAbortException,也就是说线程在ThreadState.AbortRequested状态时表示即将结束可是尚未真正结束。但是Thread.Abort方法将线程的状态置为ThreadState.AbortRequested后就立马返回了,而线程真正结束后的状态应该是ThreadState.Aborted,因此必定要注意在调用了Thread.Abort方法后,要记得循环检查Thread.ThreadState属性的值或者调用Thread.Join方法来确保被终止线程已经真正中止,只有当Thread.ThreadState属性为Aborted或Thread.Join方法返回时,才表示线程真正结束了。线程
下面我就写一个示例代码来讲明在调用Thread.Abort方法后,怎样保证线程中止后代码才会继续执行code
var thread = new Thread( new ThreadStart( () => { while (true) { //该线程会进行无限循环,本身不会结束 Thread.Sleep(100); } })); thread.IsBackground = true; thread.Start();//启动线程 thread.Abort();//调用Thread.Abort方法试图强制终止thread线程 //上面调用Thread.Abort方法后线程thread不必定立刻就被终止了,因此咱们在这里写了个循环来作检查,看线程thread是否已经真正中止。其实也能够在这里使用Thread.Join方法来等待线程thread终止,Thread.Join方法作的事情和咱们在这里写的循环效果是同样的,都是阻塞主线程直到thread线程终止为止 while (thread.ThreadState!=ThreadState.Aborted) { //当调用Abort方法后,若是thread线程的状态不为Aborted,主线程就一直在这里作循环,直到thread线程的状态变为Aborted为止 Thread.Sleep(100); } //当跳出上面的循环后就表示咱们启动的线程thread已经彻底终止了
不过请记住使用Thread.Abort方法来终止正在执行的线程并非一个好的方法,由于Abort方法是经过在线程上抛异常来终止线程的,这样可能会产生一些意想不到的问题。最好的办法是在启动的线程中加信号灯,当想要终止线程执行时就更改信号灯的状态,启动的线程当读到信号灯状态改变后本身结束代码的执行,这才是最安全的作法。blog