4

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

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

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

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

可以做得很好吗?

4

4 回答 4

8

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

如果您想真正阻塞直到它完成,您可以同步运行任务以开始。

于 2009-06-25T06:09:22.953 回答
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 
于 2009-06-25T06:38:56.933 回答
2

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

于 2009-06-27T10:36:22.183 回答
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 线程)

于 2009-06-25T06:57:01.343 回答