需求:多线程停止后点开始按钮能再次开始。多线程 OnNumberClear();//引发完成事件  threads[i].Abort(); 线程都销毁了,不能重启了,怎么解决?试图不销毁线程,让while退出循环但是失败,请教有何好办法?
private void btnTest_Click(object sender, EventArgs e)
       {
           Program();
           Action();
}
public void test()
       {
           while (true)
           {
               if (this.InvokeRequired)
               {
                   Monitor.Enter(this);//锁定,保持同步                   .....//代码省略                   if (......)
                   {
                       OnNumberClear();//引发完成事件
                   }
               }
               Monitor.Exit(this);//取消锁定
               Thread.Sleep(5);
           }
       }
private void run()
        {
            test();
        }
        public void Program()
        {
            maxThread = 50;
            threads = new Thread[maxThread];
            for (int i = 0; i < maxThread; i++)
            {
                Thread t = new Thread(run);
                t.Name = string.Format("{0}", i);
                t.IsBackground = true;//程序关闭之后,线程关闭
                threads[i] = t;
            }
        }        public void OnNumberClear()
        {
            for (int i = 0; i < maxThread; i++)
            {
                threads[i].Abort();
            }      
        }
        public void Action()
        {
            for (int i = 0; i < maxThread; i++)
            {
                threads[i].Start();
            }
        }

解决方案 »

  1.   

    挂起用Suspend,你是想挂起,还是重新点击的时候重新开始执行呢?如果要从头执行可以销毁了重建
      

  2.   


    如何重建?
    就重新Program()一次就重建了,具体可以你还要调整下代码
      

  3.   

    小时候我用过TIMER控件执行再启动。
      

  4.   


    如何重建?
    就重新Program()一次就重建了,具体可以你还要调整下代码
    我都试过了,就重新Program()也没用的,应该怎么调整
      

  5.   


    如何重建?
    就重新Program()一次就重建了,具体可以你还要调整下代码
    我都试过了,就重新Program()也没用的,应该怎么调整
    你的排他锁出问题了。
    OnNumberClear();//引发完成事件
    这句话把他自己干掉了,后来线程创建成功了,但是无法获取排他锁,所以你感觉没有成功,要在OnNumberClear方法之前先释放排他锁
      

  6.   


    如何重建?
    就重新Program()一次就重建了,具体可以你还要调整下代码
    我都试过了,就重新Program()也没用的,应该怎么调整
    你的排他锁出问题了。
    OnNumberClear();//引发完成事件
    这句话把他自己干掉了,后来线程创建成功了,但是无法获取排他锁,所以你感觉没有成功,要在OnNumberClear方法之前先释放排他锁还是不行,排它锁在onNumberClear方法前释放,就会继续执行循环语句(每次循环collectModel.RemoveAt(0);//删除ArrayList中的元素)报错:索引超出范围。必须为非负值并小于集合大小
      

  7.   


    如何重建?
    就重新Program()一次就重建了,具体可以你还要调整下代码
    我都试过了,就重新Program()也没用的,应该怎么调整
    你的排他锁出问题了。
    OnNumberClear();//引发完成事件
    这句话把他自己干掉了,后来线程创建成功了,但是无法获取排他锁,所以你感觉没有成功,要在OnNumberClear方法之前先释放排他锁还是不行,排它锁在onNumberClear方法前释放,就会继续执行循环语句(每次循环collectModel.RemoveAt(0);//删除ArrayList中的元素)报错:索引超出范围。必须为非负值并小于集合大小这是你没贴出来的代码问题了,我试了,本来的问题应该是在排他锁上,建议你先把本线程之外的线程全部终止,然后再把排他锁释放,然后将本线程终止
      

  8.   

    挂起是Suspend
    重新启动Start就可以
    看你用threads[i]记住要回收啊
      

  9.   

    使用 AutoResetEvent的set和WaitOne方法,具体看帮助文档
      

  10.   

    放弃了,最后改用BackgroundWorker多线程的方法,感觉这个很好用,比Thread多线程简单许多。
    例子:http://www.jb51.net/article/34804.htm
      

  11.   

    看了大概,使用了ManualResetEvent,希望楼主弄明白ManualResetEvent 和我说的AutoResetEvent的区别,线程同步要小心,很容易出问题。
      

  12.   


    至少BackgroundWorker开始、暂停、停止,功能不错的,停止了还能再重新开始,7楼说的重新new一下就能重新开始纯属扯淡,线程Abort()了是不能再恢复的,thread要实现重新开始貌似只能让线程暂停,做出一种停止的假象。反正网上找了很多也没找到用thread很完美的方案。
      

  13.   

    直接贴代码咯,希望能帮你解决这个问题System.Threading.AutoResetEvent autoWait = new System.Threading.AutoResetEvent(false);
                bool runFlg = true;
                bool isContinue = true;            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(
                    (obj) =>
                    {
                        autoWait.WaitOne(System.Threading.Timeout.Infinite, false);
                        while (runFlg)
                        {
                            if (!isContinue) break;
                            //To Do Something
                        }
                    }));
                //按钮暂停事件中让线程暂停(线程挂起)
                isContinue = false;            //按钮开始事件中让线程重新开始
                autoWait.Set();
                isContinue = true;            //销毁线程时
                runFlg = false;
                thread.Abort();上面只是一个伪代码,楼主实现的时候,需要调整,比如autoWait变成全局变量等。
      

  14.   


    至少BackgroundWorker开始、暂停、停止,功能不错的,停止了还能再重新开始,7楼说的重新new一下就能重新开始纯属扯淡,线程Abort()了是不能再恢复的,thread要实现重新开始貌似只能让线程暂停,做出一种停止的假象。反正网上找了很多也没找到用thread很完美的方案。
    呵呵
      

  15.   

    用 ManualResetEvent     ManualResetEvent .Reset();
        ManualResetEvent .WaitOne();暂停
    ------------------------------------ManualResetEvent.set();
    继续