简化问题:我有四个C#后台工作人员需要几分钟,几个小时才能完成。我不希望在那段时间内锁定我的用户界面。当用户点击button1时,我按下该按钮关闭:
button1.Enable = false;
我希望按钮重新启用并在所有后台工作人员完成时更新标签。怎么办呢?
详细问题: 我有4名背景工作人员被宣布为BGW1,BGW2等。
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
BGW1.RunWorkerAsync();
BGW2.RunWorkerAsync();
BGW3.RunWorkerAsync();
BGW4.RunWorkerAsync();
button1.Enabled = true;
}
尽管没有工人完成,但按钮仍然启用。 在任何backgroundworker完成语句中调用button1.Enabled = true将在其他工作人员完成之前启用该按钮。
创建任何类型的公共整数并执行while循环似乎也会锁定UI。任何一种方法来执行一个公共整数,它在没有锁定UI直到整数返回0的情况下休眠主线程?或者也许是处理后台工作者跟踪的更好方法。
答案 0 :(得分:1)
您应该循环检查IsBusy
属性,直到它返回false,此时您可以启用该按钮。请参阅
BackgroundWorker.RunWorkerAsync Method ()。
但是,现在有更好的方法可以通过await
和async
方法实现相同的目标。
答案 1 :(得分:1)
您可以在没有任何循环的情况下执行此操作。为所有后台工作者订阅RunWorkerCompletedEvent。当工人完成时,将引发此事件。然后,您可以在其事件处理程序中检查所有四个后台工作程序的状态,例如:
private void button1_Click(object sender, EventArgs e)
{
this.button1.Enabled = false;
this.BGW1.RunWorkerAsync();
this.BGW2.RunWorkerAsync();
this.BGW3.RunWorkerAsync();
this.BGW4.RunWorkerAsync();
}
private void BGW1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
RefreshButtonState();
}
private void BGW2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
RefreshButtonState();
}
private void BGW3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
RefreshButtonState();
}
private void BGW4_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
RefreshButtonState();
}
private void RefreshButtonState()
{
this.button1.Enabled = !this.backgroundWorker1.IsBusy &&
!this.backgroundWorker2.IsBusy &&
!this.backgroundWorker3.IsBusy &&
!this.backgroundWorker4.IsBusy;
}
答案 2 :(得分:0)
为此,我建议使用Task而不是thread,并且你也可以创建异步menthods并使用await来等待所有已完成的任务。
请仔细阅读本文以了解更多相关信息,http://blog.stephencleary.com/2012/02/async-and-await.html