Friday, March 17, 2006

I love anonymous delegates - I think they are extremely useful and allow me to solve some problems in very elegant ways.  However, once you really get into them, you start to see the dark side of anonymous delegates and that is unregistration.

Here's the basic problem: when binding an instance delegate to an event to handle some activity, the delegate will cache off the instance reference - thereby keeping the reference alive.  So for example, if I had a form which wanted to process some activity from an object:

class Publisher
{
   public event EventHandler OnEvent;
   ...
}

class MainForm : Form
{
   Publisher _pub = new Publisher();

   void ActivateChildForm() 
   {
      ChildForm f = new ChildForm(_pub);
      f.Show();
   }
}

class ChildForm : Form
{
   public ChildForm(Publisher pub) 
   {
      pub.OnEvent += ProcessEvent;
   }
   void ProcessEvent(object sender, EventArgs e)
   {
      listBox1.Items.Add("Event was fired!");      
   }
}

When the ChildForm instance is closed, the form won't be collected because the Publisher (_pub) is holding a reference to it.  This is easily fixed by adding some code into the FormClosing event:

class ChildForm : Form
{
   Publisher _pub;

   public ChildForm(Publisher pub)
   {
      _pub = pub;
      _pub.OnEvent += ProcessEvent;
   }

   void FormClosing(object sender, FormClosingEventArgs e)
   {
      _pub.OnEvent -= ProcessEvent; 
   }
}

Now, the form will be cleaned up when it's closed.  This is pretty standard stuff, and most people that have been using .NET for a while know all this.  Here's the rub: with .NET 2.0, we can simplify the code using anonymous delegates which are really helpful for these single-line processing event handling functions.  So, I could recode my handler as:

class ChildForm : Form
{
   public ChildForm(Publisher pub) 
   {
      pub.OnEvent += delegate { listBox1.Items.Add("Event was fired!"); }
      this.OnClosing += delegate { pub.OnEvent -= ????? }

   }
}

The issue is that I don't have a reference to the delegate as it's typed.  Under the covers, the C# compiler has generated a temporary function (or possibly even pulled it out to a separate inner class) and there's no way for me to get to the underlying function.  So, what can I do?  Well, the easiest thing to do is to save off the function:

class ChildForm : Form
{
   public ChildForm(Publisher pub) 
   {
      EventHandler eh = delegate { listBox1.Items.Add("Event was fired!"); }
       
      pub.OnEvent += eh;      
     
this.OnClosing += delegate { pub.OnEvent -= eh; }
   }
}

Now my code will function properly -- and is significantly reduced in size.  Of course, I've lost the benefit of being able to hook up events through VS.NET because it always generates seperate functions and I would need to cache off the Publisher instance as well as my delegate in that case. 

So, rule #1, always unregister the event when you are finished.  Rule #2, remember that anonymous delegates may be keep your instance alive so unregister them as well, unless the event is to be hooked up throughout the lifetime of the application.

posted on 3/17/2006 10:56:40 AM (Central Standard Time, UTC-06:00)  #   

Related Posts:
Demos + Labs for the WPF+LINQ class this week
Implementing Drag/Drop with TabControl
ATAPI assembly updated!
Adding ILDasm to VS.NET with a keyboard shortcut
Creating Extensible Applications with MAF (System.AddIn)
Creating popup windows in XBAP applications

Tracked by:
"moving companies quotes" (moving companies quotes) [Trackback]
"real audio player" (real audio player) [Trackback]
"lined wicker laundry baskets" (lined wicker laundry baskets) [Trackback]
"Alberta Incorporation" (Alberta Incorporation) [Trackback]
"dvd xcopy platinum" (dvd xcopy platinum) [Trackback]
"broker dealer information" (broker dealer information) [Trackback]
"2005 ford expedition" (2005 ford expedition) [Trackback]
"exotic canopy beds" (exotic canopy beds) [Trackback]
"What%27s a Jewish Matchmaker" (What%27s a Jewish Matchmaker) [Trackback]
"dawn of war mod" (dawn of war mod) [Trackback]
"mangosteen ORAC ounce" (mangosteen ORAC ounce) [Trackback]
"Camouflage Wetsuits" (Camouflage Wetsuits) [Trackback]
"cervical disc problems" (cervical disc problems) [Trackback]
"Flagyl and diverticulitis" (Flagyl and diverticulitis) [Trackback]
"hookah diving with out tanks" (hookah diving with out tanks) [Trackback]
"No Deposit Bonus" (No Deposit Bonus) [Trackback]
"hud property" (hud property) [Trackback]
"protonix in surgery use" (protonix in surgery use) [Trackback]
"vulnerability scanner" (vulnerability scanner) [Trackback]
"first compound microscope" (first compound microscope) [Trackback]
"open response questions" (open response questions) [Trackback]
"excel communications" (excel communications) [Trackback]
"SAGUARO CACTUS DERMATITIS" (SAGUARO CACTUS DERMATITIS) [Trackback]
"body aches and persistent fever" (body aches and persistent fever) [Trackback]
"compromises of the constitution" (compromises of the constitution) [Trackback]
"personal injury lawyer virginia" (personal injury lawyer virginia) [Trackback]
"baby photo contest" (baby photo contest) [Trackback]
"vacation rentals massachusetts" (vacation rentals massachusetts) [Trackback]
"soft serve ice cream" (soft serve ice cream) [Trackback]
"jagg oil cooler" (jagg oil cooler) [Trackback]
"actonel d" (actonel d) [Trackback]
"kayak rod holder" (kayak rod holder) [Trackback]
"residence inn seaworld" (residence inn seaworld) [Trackback]
"mineral make-up" (mineral make-up) [Trackback]
"white pages perth" (white pages perth) [Trackback]
"don gabriel cigar shop" (don gabriel cigar shop) [Trackback]
"banner graphic, greencastle" (banner graphic, greencastle) [Trackback]
"boob olympics" (boob olympics) [Trackback]
"concrete stamping houston" (concrete stamping houston) [Trackback]
"DVR DVD Recorders" (DVR DVD Recorders) [Trackback]
"hikaru no go" (hikaru no go) [Trackback]
"auto noleggio rovigo" (auto noleggio rovigo) [Trackback]
"gay massage cleveland" (gay massage cleveland) [Trackback]
"booful baby beans doll" (booful baby beans doll) [Trackback]
"go down" (go down) [Trackback]
"samsung ringtones" (samsung ringtones) [Trackback]
"fire apparatus repair" (fire apparatus repair) [Trackback]