如何实施暂停和播放使用BackgroundWorker c#恢复功能 [英] How to implement Pause & Resume functionality with BackgroundWorker c#
问题描述
我想使用BackgroundWorker实现暂停恢复和取消功能.我有一个用户控件,所有与后台工作相关的代码都写在用户控件中.我只是将用户控件添加到流布局控件上,就像用户单击按钮时一样多.我没有障碍 暂停和播放使用 ManualResetEvent 恢复功能,但是无论如何我都无法做到这一点.所以在这里,我要粘贴与用户控件类相关的代码和表单代码.
i want to implement pause resume and cancel functionality with BackgroundWorker. i have a one user control and all backgroundworker related code written in user control. i just add user control on flow layout control as many as time user click on buttons. i am fail to impelement Pause & Resume functionality with ManualResetEvent but anyway i am not being able to do it. so here i am pasting my user control class related code and my form code.
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的图片.
here i am attaching pic of mu UI how it looks.
推荐答案
向您的班级添加属性,该属性将保存bool-Sleep.订阅该更改,如果为true,则将thread.sleep设置为某个大数字,然后订阅该数字,使其变为0;如果bool仍为True,则再次将其设置为大数字.这就是我现在想到的,有更好的方法可以确保.
Add property to your class which will hold bool - Sleep . Subscribe to that change and if it's true set thread.sleep to some big number, then subscribe to that number becoming 0 and if the bool is still True set it to big number again. That's what comes to my mind now there are better ways for sure.
这篇关于如何实施暂停和播放使用BackgroundWorker c#恢复功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!