2012-04-23 13 views
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(); 
    } 

ありがとうございます!

+1

背景労働者とスレッドプール?どうして? –

+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関数の後にcancellationpending条件を追加すると正しく動作しています。とにかく、良い答えです。 P.S.進歩を報告できるように、彼はバックグラウンドワーカーを追加したと思います。ダニー –

関連する問題