Feb 24, 2011

Cross threading revisited

Once upon a long time ago I wrote a blog on cross threading, you know, trying to handle an event in one thread that was generated in another thread. Particularly dangerous on forms, since they are highly mutable. In that post, I was writing a library and I wanted to make sure I invoked the event on the thread of the event handler so that the user of my .DLL didn't have to even know things were happening on a different thread.  More recently (yesterday in fact) I was communicating with a serial device on a separate thread and I wanted to show any error messages in the GUI. The threading was already done and the BackgroundWorker class wasn't used.

A New Idiom for Event Handlers

It occurred to me that I could write an event handler that could easily handle events from the same thread or from a different thread. In fact, I think all event handlers should be written this way and then you never need to worry about breaking the handler if you move a task into a separate thread.

So instead of doing something like this:

void DangerousEventHandler(object sender, YourEventArgsClass e)
{
    //use e.Value and take your chances on updating the form directly
    //hoping that whatever generated the event is in the same thread
    //and never changes.
}

You can put your actual update code in a separate method, then write one delegate for all your event handlers and rewrite all the event handlers to use that delegate to invoke your newly separated method like this:

private delegate void UpdateFormDelegate<T>(T msg);
void ThreadSafeEventHandler(object sender, YourEventArgsClass e)
{
    if (InvokeRequired)
    {   //Specialize for whatever type e.Value is, in this case string
        Invoke(new UpdateFormDelegate<string>(UpdateFeedbackSafe), new object[] { e.Value });
    }
    else UpdateFeedbackSafe(e.Value);
}

private void UpdateFeedbackSafe(string msg)
{
    if (rtbStatus == null) return;
    if (!rtbStatus.IsDisposed) rtbStatus.AppendText(msg + "\n");
}

About Me

My photo
Tod Gentille (@todgentille) is now a Curriculum Director for Pluralsight. He's been programming professionally since well before you were born and was a software consultant for most of his career. He's also a father, husband, drummer, and windsurfer. He wants to be a guitar player but he just hasn't got the chops for it.