2013-03-30 94 views
1

我想使用BackgroundWorker實現暫停恢復和取消功能。我有一個用戶控件和用戶控件中編寫的所有與backgroundworker相關的代碼。我只是添加用戶控制流量佈局控制多達時間用戶點擊按鈕。我無法推動 暫停&恢復功能ManualResetEvent但無論如何,我無法做到這一點。所以我在這裏粘貼我的用戶控件類相關的代碼和我的表單代碼。如何使用BackgroundWorker實現暫停和恢復功能c#

public partial class ucBackgroundWorker : UserControl 
{ 
    System.ComponentModel.BackgroundWorker bgWorker = null; 
    public event Action<string, EventArgs> Done; 
    public event Action<string, EventArgs> Cancel; 
    private static bool m_continue = true; 
    private ManualResetEvent _resetEvent = new ManualResetEvent(false); 
    //Semaphore sWaiter = new Semaphore(0, 1); 

    public ucBackgroundWorker() 
    { 
     InitializeComponent(); 
     bgWorker = new System.ComponentModel.BackgroundWorker(); 
     bgWorker.WorkerSupportsCancellation = true; 
     bgWorker.WorkerReportsProgress = true; 
     bgWorker.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 
     bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); 
     bgWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 
    } 

    public void Run(int counter) 
    { 
     if (!bgWorker.IsBusy) 
     { 
      bgWorker.RunWorkerAsync(counter); 
     } 
     _resetEvent.Set(); 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     int input = int.Parse(e.Argument.ToString()); 

     this.BeginInvoke((MethodInvoker)delegate 
     { 
      lblStatus.Text = "Running"; 
     }); 

     for (int i = 1; i <= input; i++) 
     { 
      _resetEvent.WaitOne(); 
      Thread.Sleep(500); 
      (sender as System.ComponentModel.BackgroundWorker).ReportProgress(i * 10); 
      if ((sender as System.ComponentModel.BackgroundWorker).CancellationPending) 
      { 
       this.BeginInvoke((MethodInvoker)delegate 
       { 
        lblStatus.Text = "Cancel"; 
       }); 

       e.Cancel = true; 
       return; 
      } 
     } 
     Thread.Sleep(1000); 
    } 


    // This event handler deals with the results of the 
    // background operation. 
    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // First, handle the case where an exception was thrown. 
     if (e.Error != null) 
     { 
      MessageBox.Show(e.Error.Message); 
     } 
     else if (e.Cancelled) 
     { 
      if (Cancel != null) 
       Cancel(this.Name, EventArgs.Empty); 
     } 
     else 
     { 
      this.BeginInvoke((MethodInvoker)delegate 
      { 
       lblStatus.Text = "Done"; 
      }); 

      if (Done != null) 
       Done(this.Name, EventArgs.Empty); 
     } 
     _resetEvent.Reset(); 
    } 

    // This event handler updates the progress bar. 
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     pBar.Refresh(); 
     pBar.Value = e.ProgressPercentage; 
    } 

    private void btnCancel_Click(object sender, EventArgs e) 
    { 
     if (bgWorker.IsBusy) 
     { 
      bgWorker.CancelAsync(); 
     } 
    } 

    private void btnPause_Click(object sender, EventArgs e) 
    { 
     if (bgWorker.IsBusy) 
     { 
      if (btnPause.Text.ToUpper() == "PAUSE") 
      { 
       btnPause.Text = "Resume"; 
       m_continue = false; 
       _resetEvent.Reset(); 
      } 
      else if (btnPause.Text.ToUpper() == "RESUME") 
      { 

       btnPause.Text = "Pause"; 
       m_continue = true; 
       _resetEvent.Set(); 

      } 
     } 
    } 
} 

    public partial class Form3 : Form 
     { 
      ucBackgroundWorker ucBgWorker = null; 

      public Form3() 
      { 
       InitializeComponent(); 
      } 

      private void btnStart_Click(object sender, EventArgs e) 
      { 
       ucBgWorker = new ucBackgroundWorker(); 
       ucBgWorker.Done += new Action<string, EventArgs>(Worker_Done); 
       ucBgWorker.Cancel += new Action<string, EventArgs>(Worker_Cancel); 
       flowLayoutPanel1.Controls.Add(ucBgWorker); 
       ucBgWorker.Run(10); 
      } 

      void Worker_Done(string arg, EventArgs evtarg) 
      { 
       label1.Text =arg + " Done One"; 
       //System.Threading.Thread.Sleep(1000); 
      } 

      void Worker_Cancel(string arg, EventArgs evtarg) 
      { 
       label1.Text = arg + " Cancel Click"; 
       //System.Threading.Thread.Sleep(1000); 
      } 

     } 

這裏我附上mu UI的照片,看起來如何。 enter image description here

+0

可能重複[暫停/恢復循環在後臺工作](http://stackoverflow.com/questions/8359058/pause-resume-loop-in-background-worker) – Thomas

回答

1

將屬性添加到您的班級將舉行布爾 - 睡眠。訂閱該更改,如果它是真的將thread.sleep設置爲某個大數字,則訂閱該數字爲0,如果該布爾值仍然爲True,則將其重新設置爲大數字。這就是我想到的現在有更好的方法可以肯定。

+0

基本上我想實現這個暫停&恢復通過使用ManualResetEvent這個類來實現功能。任何方式感謝提示。 – Thomas

+0

任何方式我的問題解決。我的問題更新瞭解決方案 – Thomas