C# “我该怎么做?”;螺纹连接;幕后工作者?

C# “我该怎么做?”;螺纹连接;幕后工作者?,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,假设我向用户展示一个表单,并使用BackgroundWorker在幕后做一些工作 当用户单击OK时,在BackgroundWorker完成之前,我无法继续。 如果用户单击Ok时它还没有完成,我想显示一个WaitCursor,直到它完成,然后继续 实现这一点的最佳方式是什么 我知道我可以使用一个普通的旧线程,然后执行Thread.Join,但我喜欢BackgroundWorker 可以很好地完成吗?理想情况下,您应该禁用表单上的所有相关控件,然后在BackgroundWorker完成后重新启用它们

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

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

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

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


可以很好地完成吗?

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


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

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

我只会使用布尔标志和锁

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

后台线程执行相同的操作(请记住开始返回主UI线程)

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

但我不希望用户必须等待Ok按钮自动启用。我不想解释背景流程。我使用这种方法,对此非常满意。你不应该解释后台进程-只需添加进度条。进度条需要解释。用户应该注意到没有什么不同,只是单击“确定”现在几乎不会导致延迟,而之前它需要几秒钟。但是如果您阻止UI线程,用户将看不到按钮被按下-他们将单击它,看不到任何可见的更改,因为您将阻止事件循环。“我同意DoEvents并不是很好的编程实践,但即使是Microsoft也建议使用它来代替解决简单问题的硬核线程。”