多个后台工作人员完成后{C>更新用户界面

时间:2016-05-16 14:33:01

标签: c# user-interface backgroundworker

简化问题:我有四个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的情况下休眠主线程?或者也许是处理后台工作者跟踪的更好方法。

3 个答案:

答案 0 :(得分:1)

您应该循环检查IsBusy属性,直到它返回false,此时您可以启用该按钮。请参阅 BackgroundWorker.RunWorkerAsync Method ()

但是,现在有更好的方法可以通过awaitasync方法实现相同的目标。

答案 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