当用户尝试双击按钮时, backgroundWorker 将启动两次。
这是一个很好的解决方法吗?
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Some processing here
Thread.Sleep(1000);
button1.Invoke((MethodInvoker)delegate { button1.Enabled= true; });
}
// Run backgroundProcess
private void button1_Click(object sender, EventArgs e)
{
this.button1.Enabled = false;
backgroundWorker1.CancelAsync();
backgroundWorker1.RunWorkerAsync();
}
答案 0 :(得分:0)
您可以使用backgroundWorker1_RunWorkerCompleted
事件启用button1。而是在backgroundWorker1_DoWork
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.button1.Enabled = true;
//rest of operations
}
您的代码有什么问题:
您可以启用_DoWork
中的按钮,这意味着更少,因为backgroundWorker1.RunWorkerAssync();
将调用_DoWork()
按钮启用,因此第二次点击也会被执行。
答案 1 :(得分:0)
当您打算使用BackgrounWorker时,您必须处理三件基本事情。
如果要在任何执行点取消后台工作进程,请处理WorkerSupportsCancellation属性。
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.DoWork += backgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
button1.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Invoke((MethodInvoker)delegate { button1.Enabled = true; });
backgroundWorker1.DoWork -= backgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted -= backgroundWorker1_RunWorkerCompleted;
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
AppendTextBox( "Hit: " + i.ToString() + Environment.NewLine);
if (backgroundWorker1.CancellationPending)
{
break;
}
}
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
}
}
public void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
textBox1.Text += value;
}
private void button2_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy)
backgroundWorker1.CancelAsync();
}
答案 2 :(得分:0)
如果工人实际上在跑步,那几乎肯定不会。
取消是合作的。调用CancelAsync
只会将CancellationPending
标志设置为true。由后台工作人员定期检查此标志并响应取消。
正在运行的工作人员在这两行代码之间的时间间隔内获得检查该标志,检查并响应的适当点的可能性:
backgroundWorker1.CancelAsync();
backgroundWorker1.RunWorkerAsync();
非常苗条。由于工人仍在运行,RunWorkerAsync
将抛出InvalidOperationException
的可能性更大(如果工人正在运行)。