RSS 2.0
# Friday, January 25, 2008

This one may seem a little rudimentary, but it caused me to think a little about the right pattern for handling background worker threads. That is, in .NET 2.0, I could take advantage of the BackgroundWorker control. This control did a nice job of spawning a thread to do some work and alerting the application (on the UI thread) when it was complete. It also got Disposed when the containing control got disposed, alleviating the need for any end of life thread synchronization. In WPF, however, this control doesn't exist, but a class called BackgroundWorker does.

My usual approach to something like this is to create a class level ManualResetEvent and then initialize the BackgroundWorker in the constructor with something like this:

_backgroundWorker = new BackgroundWorker();
_threadStopEvent = new ManualResetEvent(false);
_backgroundWorker.DoWork += new DoWorkEventHandler(GetNowPlaying);
_backgroundWorker.WorkerSupportsCancellation = true;
_backgroundWorker.RunWorkerAsync();

Then, have the periodic worker do a timed wait on the ManualResetEvent. When the wait times out, perform the action, and when the wait is triggered, exit the loop (ending the worker thread). This usually looks something like this:

private void GetNowPlaying()
{
    while (!_threadStopEvent.WaitOne(500,false))
    {
        // Do some work
    }
}

In the normal case, I tell the thread to stop when the owning object's dispose method is called like this:

protected void Dispose(bool disposing)
{
    if (disposing)
    {
        if (!_disposed)
        {
            _threadStopEvent.Set();
            _disposed = true;
        }
    }
}

This didn't seem to work in our case. Another alternative was to call the BackgroundWorkder's CancelAsync() method. That didn't work either. The reason? Our Factory has a static NowPlaying object. So, when should we dispose our NowPlaying object? There are many instances of the Factory class created. We don't want each instance to have its own copy of the media library, so we share it across all instances. But, how do we know when to dispose of it?

It turns out, it doesn't really matter. The BackgroundWorker class does a pretty good job of cleaning up after itself. So, we can just get rid of the Dispose altogether. The BackgroundWorker takes care of terminating all of our background threads automatically. Best Practice? I'm not sure. It seems like we're not doing a very nice job of disposing of our resources, but it's pretty slick.

Friday, January 25, 2008 3:46:01 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0] -
Windows Media Player
Navigation
Categories
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Cavin Consulting
Sign In
Statistics
Total Posts: 28
This Year: 0
This Month: 0
This Week: 0
Comments: 4
All Content © 2010, Cavin Consulting
DasBlog theme 'Business' created by Christoph De Baene (delarou)