大家都知道在c#里面,我们可以使用thread.start方法来启动一个线程,当我们想停止执行的线程时可以使用thread.abort方法来强制停止正在执行的线程,但是请注意,你确定调用了thread.abort方法后线程就立刻停止了吗?答案是:不是!

下面我们来解释一下abort方法是如何工作的。因为公用语言运行时管理了所有的托管的线程,同样它能在每个线程内抛出异常。abort方法能在目标线程中抛出一个threadabortexception异常从而导致目标线程的终止。不过abort方法被调用后,目标线程可能并不是马上就终止了。因为只要目标线程正在调用非托管的代码而且还没有返回的话,该线程就不会立即终止。而如果目标线程在调用非托管的代码而且陷入了一个死循环的话,该目标线程就根本不会终止。不过这种情况只是一些特例,更多的情况是目标线程在调用托管的代码,一旦abort被调用那么该线程就立即终止了。

其实一个线程在运行时,我们可以通过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方法后,怎样保证线程停止后代码才会继续执行

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已经完全终止了  
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方法是通过在线程上抛异常来终止线程的,这样可能会产生一些意想不到的问题。最好的办法是在启动的线程中加信号灯,当想要终止线程执行时就更改信号灯的状态,启动的线程当读到信号灯状态改变后自己结束代码的执行,这才是最安全的做法。

将一个信号灯标志位置位true,然后就等待这个线程顺利结束:

usbop.threadstopflg = true;           
while ((usbreadthread.threadstate != system.threading.threadstate.stopped) && (usbreadthread.threadstate != system.threading.threadstate.aborted))  
{  
    thread.sleep(10);  
}  
usbop.threadstopflg = true;         
while ((usbreadthread.threadstate != system.threading.threadstate.stopped) && (usbreadthread.threadstate != system.threading.threadstate.aborted))
{
    thread.sleep(10);
}

在usbreadthread这个线程的循环里,会一直这样检测:

if (threadstopflg == true) //判断是否该结束线程了  
{  
    threadstopflg = false;  
    return;  
}  

到此这篇关于c#如何优雅的结束一个线程的文章就介绍到这了,更多相关c#结束线程内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!