Take care to unhook Anonymous Delegates
- by David Vallens
Anonymous delegates are great, they elimiante the need for lots of small classes that just pass values around, however care needs to be taken when using them, as they are not automatically unhooked when the function you created them in returns. In fact after it returns there is no way to unhook them.
Consider the following code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
SimpleEventSource t = new SimpleEventSource();
t.FireEvent();
FunctionWithAnonymousDelegate(t);
t.FireEvent();
}
private static void FunctionWithAnonymousDelegate(SimpleEventSource t)
{
t.MyEvent += delegate(object sender, EventArgs args)
{
Debug.WriteLine("Anonymous delegate called");
};
t.FireEvent();
}
}
public class SimpleEventSource
{
public event EventHandler MyEvent;
public void FireEvent()
{
if (MyEvent == null)
{
Debug.WriteLine("Attempting to fire event - but no ones listening");
}
else
{
Debug.WriteLine("Firing event");
MyEvent(this, EventArgs.Empty);
}
}
}
}
If you expected the anonymous delegates do die with the function that created it then you would expect the output
Attempting to fire event - but no ones listeningFiring eventAnonymous delegate calledAttempting to fire event - but no ones listening
However what you actually get is
Attempting to fire event - but no ones listeningFiring eventAnonymous delegate calledFiring eventAnonymous delegate called
In my example the issue is just slowing things down, but if your delegate modifies objects, then you could end up with dificult to diagnose bugs.
A solution to this problem is to unhook the delegate within the function
var myDelegate = delegate(){Console.WriteLine("I did it!");};
MyEvent += myDelegate;
// .... later
MyEvent -= myDelegate;