我在一个winform程序中点击一个按钮,然后会根据用户的设置同时启动多个线程执行各自的任务,如果在各个线程正常执行完毕后再次点击那个按钮重新执行任务就没有问题。但是如果还有线程没有停止就再次点击那个按钮,尽管会判断每个线程的状态是否是stop,若不是就在try-catch中about线程,但是这时程序会出现假死,整个窗体要等一会才有反应。请问应该如何处理会好一点呢?

解决方案 »

  1.   

    我今天又仔细看了一下子的程序,发现最初的版本是创建了多个线程后可以快速abort这些线程,窗口的假死情况很轻很轻,几乎就是没有。但是现在的话不知道为什么,在直接终止这些线程,窗口就开始假死了,要等好几秒钟后才有反应,在此期间,可以在vs2005的输出窗口看到有提示说:
    在 System.Threading.ThreadAbortException 中第一次偶然出现的“XXXX.dll”类型的异常
    然后一会儿会有一个:
    线程 0xXXX 已退出,返回值为 0 (0x0)。---这说明程序正在终止这些线程,或是这些线程在自己一个个的运行结束,似乎现在程序把所有的精力全放在这上面了,导致窗口那边得不到相应。这个问题怎么才能更好的处理呢?(希望高人继续跟上.....)
      

  2.   

    先判断线程是不是alive,然后最好的方法是在线程的回调函数中加入一个条件判断,每执行一次或循环一次就判断一次条件是否为真,不为真则退出函数,并正常结束线程。这样做的好处是,在你需要中止线程的时候可以留给线程一个机会自然中止,否则老是用abort的话,会出问题的。比如线程正在写一个固定格式的文件,那么这个时候如果强行abort的话,就有可能损坏这个文件的。
      

  3.   

    楼主应该MSDN里查一下thread.abort方法的说明。里面有详细的介绍的。
      

  4.   

    我每次点击按钮的时候都会判断一下各个线程isAlive,是的话就abort,再启动线程,不是的话就直接启动线程。
    另外,每个线程中没有循环,他们都是执行一个任务,任务完成(比如 1+1=2)且没有点击按钮,线程就自然死亡。
    当然,这些线程涉及到了同步问题,不过在每个同步的地方我都lock了。
      

  5.   

    干嘛去abort?你线程的事情都没做完就去强行中止它,这样行不?太多abort会导致耗去很多资源的,特别线程在运行,你去abort,线程可能不会释放干净资源。。winform开后台线程假死的问题,我看很多人提了这个问题,特别是线程里调用form的Invoke方法的,那是导致线程死锁导致的。不知道你有没有这样使用。
      

  6.   


    明白你的意思,我的意思是说,让你用将控制线程中止的条件设置为假,让线程自然退出,而不是在你要退出的时候直接abort。因为abort会很耗费资源的。明白我的意思吗
      

  7.   


    你的确说对了,我的程序就是当点击按钮后启动几个线程去执行不同的任务,每个线程执行完毕都会调用form中的一个空间的invoke将其结果显示出来。所以当下次点击的时候必须终止此次执行任务的线程,不然此次的执行结果会部分显示到下次的执行结果中。而且我跟踪时也的确发现abort线程时有时特别的耗费资源导致程序假死。
    既然你知道原因,那你能不能给我一些建议?
      

  8.   

    嘿,我明白你的意思。和我的实现的差不多,触发按钮事件,就不会abort线程,但是触发的时候是不是就要abort的了。谢啦。
      

  9.   

    你不用Invoke调用就可以了啊,就是放在Invoke里的代码直接放到线程中操作不行吗?操作完界面调用Application.DoEvents();强烈建议你不要去调用Abort ,任何时候都不要去调用,你的线程又没有while(true)之类的,它会自动结束的,如果你强行中止,你如何知道线程处理逻辑到什么程度了?这不是自己给自己找问题吗?你abort多了,最后的程序可能就崩掉了。
      

  10.   

    最好自己实现一个方法来终止线程的运行,ABORT的方式太不友好了,而且会出现未知的问题。