2009-06-25 65 views
4

假设我向用户显示表单,并使用BackgroundWorker在幕后执行一些工作。如何“Thread.Join”BackgroundWorker?

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

实现此目的的最佳方式是什么?

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

它可以做得很好吗?

回答

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 
8

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

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

+0

我不希望用户不得不等待Ok按钮来启用它自己。我不想解释后台进程。 – Blorgbeard 2009-06-25 06:27:10

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线程)

2

你可以检查是BackgroundWorker的是一个在btnOK_Click事件处理程序检查运行是否体重。 IsBusy是真的。如果是这样,请更改光标并设置一个表示OK处理程序正在等待的布尔标志。当BackgroundWorker完成其作业时,如果确定等待,则将该标志设置为false,更改光标并执行确定按钮的作业。 :-)