A while back i was trying to find a solution to the delegate gotcha and stumbled upon, even more recently, some answers to a lot of my questions… they trackback and link with each other at some point, but my entry point to this discussion was mostly through, in no specific order:
Observable property pattern, memory leaks and weak delegates for .Net. – Alexey A. Popov
Simulating “Weak Delegates†in the CLR – Greg Schechter
.Net 2.0 Generics, Anonymous Methods, and Delegate inference bug – Udi Dahan
After reviewing a lot of the different solutions, i’m currently experimenting with an idea. Given your usual suspect:
public class EventSource
{
   public event EventHandler FireEvent;
   public void OnFireEvent( )
   {
     if(null != FireEvent)
         FireEvent( this, EventArgs.Empty );
   }
}
I’ve reworked some ideas and using WeakReference, rewritten the EventSource above as follows:
public class EventSource
{
   private Dictionary<EventHandler, WeakReference> origDelgs =
           new Dictionary<EventHandler, WeakReference>();  Â
   public event EventHandler FireEvent
   {
       add
       {
           if( !origDelgs.ContainsKey( value ) )
               origDelgs.Add( value, new WeakReference( value ) );
       }
       remove
       {
            if( origDelgs.ContainsKey( value ) )
               origDelgs.Remove( value );
        }
   }
   public void OnFireEvent( )
   {
      foreach( WeakReference aref in origDelgs.Values )
      {
         if( null != aref.Target )
         {
            EventHandler hdl = (EventHandler)aref.Target;
            hdl.Invoke( this, EventArgs.Empty );
         }
      }
   }
}
Now, at least, if my sink goes out of scope, it won’t get resurrected 🙂
Will continue experimenting with this idea and see how it performs….