0

我有以下功能,除了停止按钮外,它们都可以正常工作。它正在停止线程池,但是当我再次单击启动时,它显示 backgroundworker 仍然很忙。暂停也有效。

如何正确停止后台工作程序和所有线程池?

    public bool stop = false;
    private object signal = new object();
    private static EventWaitHandle PauseEvent = new EventWaitHandle(false, EventResetMode.ManualReset);

    private void start_button_Click(object sender, EventArgs e)
    {

        if (this._BackgroundWorker.IsBusy)
        {
            MessageBox.Show("busy", "test", MessageBoxButtons.OK);
            return;
        }
        /////////////////////////////////////////////////////////////////////////
        //some code
        /////////////////////////////////////////////////////////////////////////
                starting();
    }



    private void stop_button_Click(object sender, EventArgs e)
    {
        if (start == true)
        {
            stop = true;
            //this._BackgroundWorker.CancelAsync();
              progressBar1.Value = 0;
        /////////////////////////////////////////////////////////////////////////
        //some code
        /////////////////////////////////////////////////////////////////////////
        }
    }


    private void starting()
    {
            ThreadPool.SetMinThreads(5, 5);
            ThreadPool.SetMaxThreads(10, 10);
        /////////////////////////////////////////////////////////////////////////
        //some code
        /////////////////////////////////////////////////////////////////////////
            this._BackgroundWorker.WorkerReportsProgress = true;
            this._BackgroundWorker.WorkerSupportsCancellation = true;
            this._BackgroundWorker.RunWorkerAsync();
    }


    private void _BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        if (this._BackgroundWorker.CancellationPending)
        {
            e.Cancel = true;
            return;
        }
        /////////////////////////////////////////////////////////////////////////
        //some code
        /////////////////////////////////////////////////////////////////////////
        for (int i = 0; i < cnt; i++)
        {
           string argument = this.listView1.CheckedItems[i].Text;
           this.DoSend(argument);
        }
    }

    private void DoSend(object sender)
    {
        int activeWorkers = 0;
        StreamReader reader = new StreamReader(E_LIST);
        do
        {
                lock (reader)
                {
                    line = reader.ReadLine();
                }
        /////////////////////////////////////////////////////////////////////////
                //some code
        /////////////////////////////////////////////////////////////////////////
                lock (signal) 
                {
                    ++activeWorkers; // keep track of active workers
                }
                ThreadPool.QueueUserWorkItem(
                        o =>
                        {
                            myfunction(argument);
                            lock (signal) // signal termination
                            {
                                --activeWorkers;
                                Monitor.Pulse(signal);
                            }
                        }, state);

                lock (signal)
                {
                    while (activeWorkers > 0 || stop == true)
                    {
                        Monitor.Wait(signal);
                        this._BackgroundWorker.CancelAsync();
                    }
                }

                this.add();

                crt++;
            }
                //start progressbar
                int iProgressPercentage = (int)(((double)crt / (double)total) * 100);
                if (iProgressPercentage <= 100)
                    _BackgroundWorker.ReportProgress(iProgressPercentage);
                //end progresbar

                PauseEvent.WaitOne();   
        }
        while (reader.Peek() != -1);
        reader.Close();
    }

谢谢!

4

1 回答 1

0

我会考虑解雇聘请的编码员。没有必要以这种方式同时进行这两种操作。很乱。

对于这个问题 -

  1. 您需要在后台工作人员上调用取消并等待它停止。
  2. 您需要在 for 循环中添加取消检查。

         for (int i = 0; i < cnt; i++)
         {
             if (this._BackgroundWorker.CancellationPending)
             {
                 e.Cancel = true;
                 return;
             }
    
             string argument = this.listView1.CheckedItems[i].Text;
             this.DoSend(argument);
         }
    
于 2012-04-23T01:06:58.803 回答