Unhandled exceptions in BackgroundWorker

What you’re describing is not the defined behavior of BackgroundWorker. You’re doing something wrong, I suspect.

Here’s a little sample that proves BackgroundWorker eats exceptions in DoWork, and makes them available to you in RunWorkerCompleted:

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => 
    { 
        throw new InvalidOperationException("oh shiznit!"); 
    };
worker.RunWorkerCompleted += (sender, e) =>
    {
        if(e.Error != null)
        {
            MessageBox.Show("There was an error! " + e.Error.ToString());
        }
    };
worker.RunWorkerAsync();

My psychic debugging skills are revealing your problem to me: You are accessing e.Result in your RunWorkerCompleted handler — if there’s an e.Error, you must handle it without accessing e.Result. For example, the following code is bad, bad, bad, and will throw an exception at runtime:

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => 
    { 
        throw new InvalidOperationException("oh shiznit!"); 
    };
worker.RunWorkerCompleted += (sender, e) =>
    {
        // OH NOOOOOOOES! Runtime exception, you can't access e.Result if there's an
        // error. You can check for errors using e.Error.
        var result = e.Result; 
    };
worker.RunWorkerAsync();

Here’s a proper implementation of the RunWorkerCompleted event handler:

private void RunWorkerCompletedHandler(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error == null)
    {
       DoSomethingWith(e.Result); // Access e.Result only if no error occurred.
    }
}

VOILA, you won’t receive runtime exceptions.

Leave a Comment