2011-05-07 102 views
2

在主线程中,我有一个Timer。在Tick事件中,我运行BackgroundWorker。我在那里做了一些事情,之后BackgroundWorker调用RunWorkerCompleted事件。等待BackgroundWorker RunWorker完成

在主线程中我有功能Stop。该功能禁用Timer。但是我想在他工作时等待BackgroundWorker

例如:

public void Next() 
{ 

    // Start the asynchronous operation 
    if (!this._backgroundWorker.IsBusy) 
     this._backgroundWorker.RunWorkerAsync(); 

} 

private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    DoSomething(); 

} 


private void _backgroundWorker_RunWorkerCompleted(object sender, 
    RunWorkerCompletedEventArgs e) 
{ 
    DoSomethingElse(); 
} 

public void Stop() 
{ 
    this._timer.Enabled = false; 
} 

所以我的问题是如何等待RunWorkerCompleted事件的BackgroundWorker?我需要等到DoSomethingElse();完成。

感谢

+2

没有。你不会等待后台工作人员......这就是为什么它叫做后台工作人员 - 你的应用程序在后台工作人员正在工作时继续进行工作。您将一个事件监听器附加到您的应用程序,应该在后台工作人员完成后触发,然后处理数据。 – ppumkin 2011-05-07 13:46:23

+0

ariba! http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx – ppumkin 2011-05-07 13:47:12

+0

私人小组backgroundWorker1_RunWorkerCompleted(_ BYVAL发件人作为对象,BYVALË作为RunWorkerCompletedEventArgs)_ 把手backgroundWorker1.RunWorkerCompleted – ppumkin 2011-05-07 13:48:39

回答

1

如果你只需要两个线程,让那个叫this._backgroundWorker.RunWorkerAsync线程();在调用此方法并在DoSomethingElse()之后调用任何想要发生的事件后,它将死亡。相同的块如下

 private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 

DoSomethingElse(); 
DoSomethingAfterSomethingElse(); 

     } 

否则,你就停止线程启动另一个,然后再返回,这违背了多线程的目的范围内?

2

处理在后台操作完成,已被取消或引发异常时发生的BackgroundWorker.RunWorkerCompleted事件。

// This event handler deals with the results of the 
// background operation. 

private void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e) 
{ 
    // First, handle the case where an exception was thrown. 
    if (e.Error != null) 
    { 
    } 
    else if (e.Cancelled) 
    { 
     // Next, handle the case where the user canceled 
     // the operation. 
     // Note that due to a race condition in 
     // the DoWork event handler, the Cancelled 
     // flag may not have been set, even though 
     // CancelAsync was called. 
    } 
    else 
    { 
     // Finally, handle the case where the operation 
     // succeeded. 
    } 

} 
1

我认为BackgroundWorker.IsBusy属性是唯一可以在这种情况下帮助你的成员。希望下面的逻辑会做你所需要的。

//Add a class member 
private bool stopped; 

public void Stop() 
{  
    if (!this._backgroundWorker.IsBusy) 
    { 
     this._timer.Enabled = false; 
     stopped = false; 
    } 
    else 
    { 
     stopped = true; 
    } 

} 

private void _backgroundWorker_RunWorkerCompleted(object sender,  RunWorkerCompletedEventArgs e) 
{  
    DoSomethingElse(); 

    if (stopped) 
    { 
      this._timer.Enabled = false; 
      stopped = false; 
    } 
} 
0

这里有一个方法来阻止/冻结主线程,直到你的后台工作完成:

public void Stop() 
{ 
    if (!_backgroundWorker.IsBusy) 
    { 
     _timer.Enabled = false; 

     // Stop/Freeze the main thread until the background worker finishes 
     while (_backgroundWorker.IsBusy) 
     { 
      Thread.Sleep(100); 
     } 
    } 
} 

现在,如果您的应用程序使用一种形式,我只想禁用整体形式和节目的消息让用户知道应用程序正在等待该过程完成。您也可以使用标志来禁用表单关闭。

private bool _canClose; 

public void Stop() 
{ 
    if (!_backgroundWorker.IsBusy) 
    { 
     _timer.Enabled = false; 
     // Don't let the user do anything in the form until the background worker finishes 
     this.IsEnabled = false; 
     _label.Text = "Waiting for the process to finish"; 
     _canClose = false; 
    } 
} 
private void _backgroundWorker_RunWorkerCompleted(object sender, 
    RunWorkerCompletedEventArgs e) 
{ 
    DoSomethingElse(); 
    // Allow the user to close the form 
    this.IsEnabled = true; 
    _canClose = true; 
} 

private void MainWindow_Closing(object sender, CancelEventArgs e) 
{ 
    e.Cancel = !_canClose; 
}