我怎么“Thread.Join”一个BackgroundWorker?

时间:2009-06-25 06:06:57

标签: c# multithreading backgroundworker

假设我正在向用户显示表单,并使用BackgroundWorker在幕后进行一些工作。

当用户单击“确定”时,在BackgroundWorker完成之前,我无法继续。 如果在用户单击“确定”时尚未完成,我想显示WaitCursor,直到有,然后继续。

实施此方法的最佳方式是什么?

我知道我可以使用普通的旧线程,然后执行Thread.Join,但我喜欢BackgroundWorker。

可以很好地完成吗?

4 个答案:

答案 0 :(得分:8)

理想情况下,您应该禁用表单上的所有相关控件,然后在BackgroundWorker完成时重新启用它们。这样你就不会得到一个锁定的用户界面 - 你可以有一个取消按钮等。

如果您希望实际阻止直到它完成,您可以同步运行任务以开始。

答案 1 :(得分:8)

您可以使用此代码,而不是BW

var resetEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(state =>
                {
                    Thread.Sleep(5000);//LongRunning task, async call
                    resetEvent.Set();
                });
resetEvent.WaitOne();// blocking call, when user clicks OK 

答案 2 :(得分:2)

您可以通过检查btnOK_Click事件处理程序来检查是否正在运行BackgroundWorker,以查看bw.IsBusy是否为true。如果是这样,请更改游标并设置一个布尔标志,指示OK处理程序正在等待。当BackgroundWorker完成其作业检查是否正在等待时,如果是,则将标志设置为false更改光标并执行“确定”按钮的作业。 : - )

答案 3 :(得分:0)

我只是使用布尔标志和锁。

object waitlock = new object();
bool isBackgroundWorkerCompleted = false;
bool isOKButtonPressed = false;

private void onPress(...) 
{
    lock(waitlock) 
    {
      isOKButtonPressed = true;
      if (isBackgroundWorkerCompleted) DoNextStep();
      else cursor.Wait(); //psuedo-code - use whatever the actual call is...
    }
}

后台线程执行相同的技巧(只记得BeginInvoke回到主UI线程)