Derek Lakin

Enhancing the BackgroundWorker Class

Background

Amongst the inner complexities of Titan, there are a number of cases where I’m executing some actions asynchronously by using the BackgroundWorker class. These are primarily in the controller class which handles calls from the user interface to the back-end service providers for actions such as getting the account tree, creating new folders, etc.

The flow through the application is (simply) illustrated in the following diagram:

BackgroundWorker

Figure 1. Background task flow.

  1. The user interface makes a request on the Controller.
  2. The Controller creates a BackgroundWorker instance and calls RunWorkerAsync, passing in the required parameter.
  3. The BackgroundWorker makes the necessary calls on the Service Provider and then raises the RunWorkerCompleted event when it’s done.
  4. The Controller sends any response to the user interface.

So, What’s the Problem?

Take uploading a new file for example. When the files has been uploaded, the user interface needs to know which file has just been uploaded so that the user interface can be updated to reflect that the file is now synchronized. Titan enables users to upload or download more than one file at a time, so there could be multiple transfer operations happening at the same time. Which means that the controller needs to know which operation has just finished.

The BackgroundWorker class enables you to pass a parameter to the

RunWorkerAsync method, which you can retrieve from the Argument property of the DoWorkEventArgs. Once you’ve finished, you can specify a result in the Result property of the same DoWorkEventArgs. This result is then available in the Result property of the RunWorkerCompletedEventArgs in the RunWorkerCompleted event handler. However, there’s no access to the original argument that you supplied, which in my case makes it difficult to tie up which upload (for example) has completed.

OK, So What’s the Solution?

One potential solution would be to create a struct that contains the result that I wanted to return initially and also the original argument, but personally I don’t like these kind of solutions. It’s like having an event args inside an event args!

The solution I employed was to create an EnhancedBackgroundWorker class that simply exposes the original argument. All it does is to provide a new RunWorkerAsync method, which stores the supplied argument (which is exposed as the Argument property), and then calls the base implementation of RunWorkerAsync.

The following code shows the EnhancedBackgroundWorker class.

using System.ComponentModel; namespace DerekLakin.Libraries.Utilities.Thread { ///

/// Enhanced class that stores the /// argument supplied to the ``RunWorkerAsync /// method so that it is available in the relevant event handlers. /// public class EnhancedBackgroundWorker : BackgroundWorker { public object Argument { get; set; } public new void RunWorkerAsync(object argument) { this.Argument = argument; base.RunWorkerAsync(argument); } } }

Now, in the RunWorkerCompleted event handler, I can access the originally supplied argument from the EnhancedBackgroundWorker (which is the sender parameter). Simple but effective. I like those kinds of solutions :)

This work is licensed under a [Creative Commons Attribution By license.](http://creativecommons.org/licenses/by/3.0/)
[![kick it on DotNetKicks.com](http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fcloudstore.blogspot.com%2f2008%2f05%2fenhancing-backgroundworker-class.html&bgcolor=47505F&cbgcolor=FFFFFF)](http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fcloudstore.blogspot.com%2f2008%2f05%2fenhancing-backgroundworker-class.html)