多个后台工作人员完成后 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方法().

但是,现在有更好的方法可以用 awaitasync 方法实现同样的事情。

您可以在没有任何循环的情况下执行此操作。为所有后台工作者订阅 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;
}