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;
}
精彩评论