开发者

Wait for BackgroundWorker RunWorkerCompleted

In the main thread I have a Timer. In the Tick event I run a BackgroundWorker. I do some things there and after that BackgroundWorker calls RunWorkerCompleted event.

In the main thread I have function Stop. This function disables the Timer. But I want wait for BackgroundWorker when he is working.

For example:

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

So my question is how wait for RunWorkerCompleted event of BackgroundWorker? I need to w开发者_运维知识库ait until DoSomethingElse(); is finished.

Thanks


Handle the BackgroundWorker.RunWorkerCompleted event which occures when the background operation has completed, has been canceled, or has raised an exception.

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

}


If you only require two threads, allow the thread that called this._backgroundWorker.RunWorkerAsync(); to die after it calls this method and call anything you want to occur after DoSomethingElse(); within the same block as below

        private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

DoSomethingElse();
DoSomethingAfterSomethingElse();

        }

Otherwise you are halting a thread to start another and then returning, which defeats the purpose of multiple threads?


I think BackgroundWorker.IsBusy property is the only member that can help you in this case. Hope below logic will do what you need.

//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;
    }
} 


Here is a way to stop/freeze the main thread until your background worker finishes:

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);
        }
    }
}

Now if your application uses a form, I would just disable the whole form and show message letting the user know the the application is waiting for the process to finish. You can also have flag to disable the form from closing.

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜