2012-04-23 2 views
0

У меня есть следующие функции, которые работают отлично, кроме кнопки остановки. Он останавливает пулы потоков, но когда я снова нажимаю на кнопку, это показывает, что фоновая работа по-прежнему занята. Пауза тоже работает.кнопка остановки для фонового рабочего и threadpool

Как я могу правильно прекратить работу фонового рабочего и всех потоков?

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(); 
    } 

Спасибо!

+1

фон работника и Threadpool? Зачем? –

+0

Да, не работает ли BackgroundWorker в потоке ThreadPool? –

+0

Таким образом, наемный кодер решил заставить его работать. Я просто хочу, чтобы кнопка останова работала. –

ответ

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); 
        } 
    
+0

Благодарю вас за ответ. Я уже пробовал это несколько секунд, прежде чем проверять этот поток, и он работает правильно, если добавить функцию отмены состояния после функции dosend. в любом случае, хороший ответ. Постскриптум Полагаю, он добавил, что фокусник может сообщить о прогрессе. Не знаю –

Смежные вопросы