Sunday, April 24, 2011

Another go at Blogger

I had given up on Blogger because it looked like it wouldn't automatically word wrap.  But, there was some CSS that got copied from Stack Overflow when I copied some text for the previous post.  When I figured that out, word wrapping worked as expected.

So, here I am again.  I tried out WordPress in the meantime, but am afraid that their ads may eventually become as obtrusive and off-topic as the ones over at LiveJournal.

Monday, April 11, 2011

Take some repetition out of safely raising events in C#

Recently, I stumbled across this page:  http://stackoverflow.com/questions/786383/c-events-and-thread-safety This wasn't what I was looking for at the time, but the comment by JP Alioto is just so beautiful.

Events in C# are a bit weird.  One reason is that they can become null, and because no one wants their program to crash with a NullReferenceException, we had numerous methods that looked like this (where EventOccurred is a delegate of type
EventHandler<EventOccurredEventArgs>):
private void OnEventOccurred(EventOccurredEventArgs args)
{
    var handler = EventOccurred;
    if ( handler != null )
    {
        handler(this, args);
    }
}
Due to their nature, the event delegates are often used in multi-threaded code and could potentially become null at any point in time.  To correctly deal with that problem, the copy of the handler on the first line of the method is required to prevent problems when the last delegate method is removed from the handler after the compare to null but before we invoke it.  (event handlers are immutable, so there's no chance of EventOccurred becoming null while we're invoking it):

We literally had dozens of these methods scattered through our source code, one for each EventHandler type in each class that used it.  But, adding the following extension method means we never have to write that boilerplate code ever again:
public static class EventHandlerExtensions
{
    public static void Raise<TEventArgs>(this EventHandler<TEventArgs> handler,
        object sender, TEventArgs args) where TEventArgs : EventArgs
    {
        if (handler != null) handler(sender, args);
    }
}
Because it's a static method, it can be invoked on even a null delegate and doesn't need to be copied to each class that uses it.

Because the handler is passed as a parameter to the method, a copy has already been made, so we don't need to make a local temporary to test against null and invoke:  the act of method calling makes that copy automatically for us!

Because it's generic, the compiler and CLR makes one for every EventHandler type we could invoke it on, automatically.

So, I've replaced those dozens of boilerplates with a single line like this:
EventOccurred.Raise(this, new EventOccurredEventArgs());
Beautiful!  (Microsoft's Framework Design Guidelines for .NET indicate that "raise" is the correct term to use when referring to what happens to an event.  [Other systems use "fire" or "signal."])

That really brightened my day a few weeks ago, and I wanted to share it yet another time on the web to increase the likelihood that folks will see it and adopt it.

First post!

LiveJournal started having just too many advertisements.  Annoying advertisements:  full screen, animated, with sound.  Just not cool.  So, now, I'm trying out blogger.  Maybe, at some point, I'll try to move some of my better posts from LiveJournal to here, but not tonight.