Background Worker, Part 1

Many times in many projects I have worked on, there have been requirements to go out and execute some long running method. I have played with various methods of doing this before, like using IAsyncResult, with a fair amount of success. After coming across this requirement again in my current project and having been a fair amount of time since I last used this pattern, I decided to explore some of the current options for WPF.

In my research I came across and excellent CodeProject article with examples of the BackgroundWorker object version the IAsyncResult pattern. In the article is a nice sample project that shows how both of the ideas can be implemented as well. For reasons unknown even to me, I settled on the BackgroundWorker object, I guess because I have never really liked using the IAsyncResult stuff.

First, some information about the BackgroundWorker object. This object definitely relies heavily on events. If you haven’t used events or are not used to subscribing and unsubscribing from events, you may find it a bit easier to use the IAsyncResult pattern. There are two (three really, but the third is for reporting progress) events that are of major importance, DoWork and RunWorkerCompleted.

The DoWork event is where you are going to execute your long running method. This event is raised when the RunWorkerAsync method is called on the BackgroundWorker object. The DoWorkEventArgs that are passed in the event delegate an Argument you can use when starting your long running process and a Result that can be used to pass back a result of the long running method.

You will be able to access this result when the RunWorkerCompleted event is raised, immediately after the completion of the DoWork event delegates. In the parameters to the RunWorkerCompleted delegate, you will have access to result if some more processing needs to be done with it with the RunWorkerCompletedEventArgs. You will also be able to see if there was an exception thrown in the DoWork delegates, or if the an outside process has requested to cancel the operation on the BackgroundWorker by calling the CancelAsync method.

Cancelling the BackgroundWorker must be set up from the beginning by setting the WorkerSupportsCancellation boolean to “true” before calling RunWorkerAsync . The same goes for the ReportProgress method.

If you are going to be doing something like running a for loop in you long running method where you are able to report progress, you will want to make sure that you also set WorkerReportsProgress property to “true” as well. The ReportProgress method simply takes a double value that should represent the percentage of progress. The ProgressChanged delegate parameter will give you access to this percentage in the ProgressPercentage property of the ProgressChangedEventArgs.

And that's it. Wiring this up can be a little tricky. In part 2 of this series, I’ll be building a reusable class that should simplify this process a little bit. Happy codes!

Share this post!

0 comments:

Post a Comment