假设我正在向用户显示表单,并使用BackgroundWorker在幕后进行一些工作。
当用户单击“确定”时,在BackgroundWorker完成之前,我无法继续。 如果在用户单击“确定”时尚未完成,我想显示WaitCursor,直到有,然后继续。
实施此方法的最佳方式是什么?
我知道我可以使用普通的旧线程,然后执行Thread.Join,但我喜欢BackgroundWorker。
可以很好地完成吗?
答案 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线程)