Michael Repucci
Michael Repucci

Reputation: 1663

Can I call RunWorkerAsync() from within RunWorkerCompleted() on a BackgroundWorker?

I have a background worker that I've set up which I'd like to potentially restart after it completes. That is, after DoWork() has completed, if the result was not successful, I want to call RunWorkerAsync() again from within the RunWorkerCompleted() handler. Can I be assured that IsBusy=false when I'm inside RunWorkerCompleted()?

For example:

void myThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if ((e.Error == null) && !e.Cancelled && (bool)e.Result)
        // do stuff
    else
        myThread.RunWorkerAsync();
}

I can't seem to find confirmation of this behavior anywhere.

Upvotes: 3

Views: 1472

Answers (2)

Peter Duniho
Peter Duniho

Reputation: 70701

Unfortunately, the documentation is not clear on the question. On top of that, the code example for the IsBusy property as actually pretty awful, in that it spin-waits on the property and calls Application.DoEvents() in the loop.

That said, as others have suggested, the most sensible design is for the flag to be true only when the async worker is actually running. I.e. when the DoWork event handler returns, it should be set back to false. And indeed, if one looks at the implementation, one sees this:

private void AsyncOperationCompleted(object arg)
{
    isRunning = false;
    cancellationPending = false;
    OnRunWorkerCompleted((RunWorkerCompletedEventArgs)arg);
}

public bool IsBusy
{
    get
    {
        return isRunning;
    }
}

The isRunning flag here is what the IsBusy property returns, and it's what RunWorkerAsync() checks to see whether the exception should be thrown. As can be seen here, the implementation sets it back to false before raising the RunWorkerCompleted event.

So, yes…it's perfectly safe to call RunWorkerAsync() from the RunWorkerCompleted event handler.

Without this being documented, there's the remote possibility the implementation could change. But at this stage, I would be very surprised if that happened. Especially with the code being open-sourced, the implementation becomes as much a specification of behavior as anything else.

Upvotes: 1

Jonathan Allen
Jonathan Allen

Reputation: 70327

I don't see any reason why not. By definition it is done, so IsBusy should always be false. And you are back on the UI thread where you belong.

Upvotes: 1

Related Questions