多个后台工作人员完成后 C# 更新 UI
C# update UI after multiple background workers finish
简化问题:我有四个 C# 后台工作人员,需要几分钟、几个小时才能完成。我不想在那段时间锁定我的 UI。当用户单击按钮 1 时,我让按钮自行关闭:
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;
}
尽管 none 的工作人员已完成,但该按钮已启用。
在任何后台工作人员完成语句中调用 button1.Enabled = true 将在其他工作人员完成之前启用该按钮。
创建任何类型的 public 整数并执行 while 循环似乎也可以锁定 UI。有什么方法可以使 public 整数休眠主线程而不锁定 UI 直到整数 returns 为 0?或者也许是处理后台工作人员跟踪的更好方法。
您应该循环检查 IsBusy
属性 直到它 returns 为假,此时您可以启用该按钮。请参阅
BackgroundWorker.RunWorkerAsync方法().
但是,现在有更好的方法可以用 await
和 async
方法实现同样的事情。
您可以在没有任何循环的情况下执行此操作。为所有后台工作者订阅 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;
}
简化问题:我有四个 C# 后台工作人员,需要几分钟、几个小时才能完成。我不想在那段时间锁定我的 UI。当用户单击按钮 1 时,我让按钮自行关闭:
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;
}
尽管 none 的工作人员已完成,但该按钮已启用。 在任何后台工作人员完成语句中调用 button1.Enabled = true 将在其他工作人员完成之前启用该按钮。
创建任何类型的 public 整数并执行 while 循环似乎也可以锁定 UI。有什么方法可以使 public 整数休眠主线程而不锁定 UI 直到整数 returns 为 0?或者也许是处理后台工作人员跟踪的更好方法。
您应该循环检查 IsBusy
属性 直到它 returns 为假,此时您可以启用该按钮。请参阅
BackgroundWorker.RunWorkerAsync方法().
但是,现在有更好的方法可以用 await
和 async
方法实现同样的事情。
您可以在没有任何循环的情况下执行此操作。为所有后台工作者订阅 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;
}