在C#中启用线程后,如果试图使用Abort方法来终止线程,那么必定会抛出“正在终止线程”的异常,一开始我也想过如何来避免这种异常出现,花了不少气力,但最后发现全是徒劳。
原因是一个正在运行的线程被终止在C#的机制中是属于非正常结束,所以必定会爆出异常,所以我们也大可不必因为在代码方面的“洁癖”非得找到一个方法来阻止这种异常出现。
也有人提出采用join()方法来阻止,但很多情况下这并不能完全满足我们的要求,比如我们有一个后台的监听线程,如果我们的确想终止它,如果我们采用了join方法,那么我们不想发生的情况就会出现,我们的界面会因为执行了join而卡死在那里,为什么呢?因为我们的监听线程一般来说都是一个持续运行的线程,所以我们大可不必因为介意爆出异常而采用join的方法而导致程序假死。
我也在网上看见有人提出过,要终止线程最好是在执行线程的代码中自然终止,这个说法本身没有错,但对于我上面说到的监听线程,要自然结束是不可能办到的。
从上面的分析我们可以看出,C#中的线程一旦开启,那么只有等这个线程执行完,自然结束,自然被系统回收才不会爆出异常,任何一种外部的强制中断都会被认为是异常的,任意一个线程在本质上都和我们的主线程(Main函数所在的线程)一样,都必须按照顺序执行完所有的语句方才结束当前线程,如果在所有的语句没有执行完的时候就被终止了,这至少是与我们设计的理想状态有差异的。
所以我觉得在遇到C#中的“正在终止线程”异常的时候,可以大胆的用try{}catch()来处理(丢弃异常信息或将异常友好化),而不是阻止这个异常的出现,阻止这个异常的出现明显有两个坏处:
第一、耗费的代价实在太高
第二、对于线程的干涉手段过于复杂,不便于维护线程
我的解决方法是:
按 “停止” 按钮后,赋值某个变量为False,在线程执行的循环任务While、Foreach 里加上判断语句 if (!tt) { continue; },效果为按下停止按钮后,跳出循环。。等同于不执行任务了,其实线程还没有关闭,只是在空闲中,可以新开一个线程在后台关闭线程1,然后再自动关闭自身。这样也解决了t1.Join();卡死界面的问题。