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

时间:2021-07-14 20:43:37

Say I'm showing the user a form, and using a BackgroundWorker to do some work behind the scenes.

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

When the user clicks OK, I cannot continue until the BackgroundWorker has completed. If it hasn't finished when the user clicks Ok, I want to show a WaitCursor until it has, and then continue.

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

What's the best way to implement this?

实现这个的最佳方法是什么?

I know I could use a plain old Thread, and then do Thread.Join, but I like BackgroundWorker.

我知道我可以使用一个普通的老线程,然后做Thread.Join,但我喜欢BackgroundWorker。

Can it be done nicely?

可以做得很好吗?

4 个解决方案

#1


You could use this code, instead of BW

您可以使用此代码,而不是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


Ideally, you should disable all the relevant controls on the form, then re-enable them when the BackgroundWorker completes. That way you won't get a locked UI - and you can have a cancel button etc.

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

If you wanted to actually block until it had finished, you could just run the task synchronously to start with.

如果你想要实际阻塞直到它完成,你可以同步运行任务开始。

#3


You could check is the BackgroundWorker is running with a check in the btnOK_Click event handler to see if bw.IsBusy is true. If so change the cursor and set a boolean flag that indicates that OK handler is waiting. When BackgroundWorker finishes its job check if ok had been waiting, if so, set the flag to false change the cursor and do the job of the OK button. :-)

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

#4


I'd just use boolean flags and a lock.

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

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...
    }
}

Background thread does the same trick (just remember to BeginInvoke back to the main UI thread)

后台线程做同样的技巧(只记得BeginInvoke回到主UI线程)

#1


You could use this code, instead of BW

您可以使用此代码,而不是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


Ideally, you should disable all the relevant controls on the form, then re-enable them when the BackgroundWorker completes. That way you won't get a locked UI - and you can have a cancel button etc.

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

If you wanted to actually block until it had finished, you could just run the task synchronously to start with.

如果你想要实际阻塞直到它完成,你可以同步运行任务开始。

#3


You could check is the BackgroundWorker is running with a check in the btnOK_Click event handler to see if bw.IsBusy is true. If so change the cursor and set a boolean flag that indicates that OK handler is waiting. When BackgroundWorker finishes its job check if ok had been waiting, if so, set the flag to false change the cursor and do the job of the OK button. :-)

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

#4


I'd just use boolean flags and a lock.

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

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...
    }
}

Background thread does the same trick (just remember to BeginInvoke back to the main UI thread)

后台线程做同样的技巧(只记得BeginInvoke回到主UI线程)