Multicast Delegate Gotcha

There are enough multicast delegate samples in .Net available on coding websites including MSDN to get you started on how to make use of them. The ‘why’ is tackled on some of them but not many include a section on “things to look out for”. This post details one such gotcha: using it in the Observer Pattern.

Let’s start with a commonly published multicast delegate sample, flavoured with Observer Pattern language:

public class Subject
{
   public delegate void EventHandler(object from, EventArgs e);
   public event EventHandler Notify;

   public Void OnNotify(EventArgs e) {
   if(null != FireEvent)
      Notify (this, e);
   }
}
public class ObserverA
{
   public void Notify(object from, EventArgs e) {...}
}

This design has several advantages and is endorsed by popularity of use in ASP.Net, so why not use the model outside that environment? For instance, an observer simply needs to subscribe by:

ObserverA obs = new ObserverA();
subjectInstance.Notify += new EventHandler(obs.Notify);

The burden of managing subscriptions is relegated 🙂 to the multicast delegate. No more foreach loops and keeping references on the observers. So, on the surface, all seems well in paradise. Further, the loose coupling between subject and observer via an interface [the delegate] promotes a warm and fuzzy feeling. The only snag is scope.

None of the samples you find deal with scope effectively since most of them deal with observers as either static methods [probably the most famous] or with methods inside and ASP.Net page cycle. And things can get fuzzy there. My next challenge is, what happens when Observer goes out of scope?

In order to clean up properly, the observer has the responsibility of unsubscribing. If it doesn’t, the subject will just “resurrect” it each time it fires an event, even you dispose your observer. Ideally then, in order to overcome this problem, the “destructor” on the observer needs to unsubscribe, if subscribed. To do this, the observer must keep a handle on the subject [still part of the pattern rules]in order to:

subjectInstance.Notify -= myEventHandlerInstance;

Whic means the observer starts to take on more form:

public class ObserverA
{
   private Subject source;
   private EventHandler myEventHandlerInstance;
   public ObserverA(Subject subjectInstance) { source = subjectInstance; }
   public void Notify(object from, EventArgs e) {...}
}

Now we have each observer maintaining a reference to the subject instance so that if the observers fall out of scope, they can clean up their subscription. But now what happens if the subject instance goes out of scope first? How does it know notify observers of its unavailability? First jump is create a “DyingEvent” which becomes a mandatory subscription for all observers: Yuk! But thinking some more on it, does it even matter? If the subject dies, the observers won’t receive any more notifications, but then when they die, they try “unsubscribe”. Oops. Gotcha!

Any ideas?

Other references:
Softsteel Solutions: C# Tutorial Lesson 16: Delegates and Events
A Beginner’s Guide to Delegates