2013-03-30 97 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