When are anonymous delegates removed from events?

521 views Asked by At

If I write something like

myDataModel.ContentLoaded += (o,e) => { DoSomething(); }

When (if ever) is that anonymous delegate removed from the event?

As a quick example, I could write this program

class Program
{
    public event EventHandler<EventArgs> MyEvent = delegate { };

    static void Main(string[] args)
    {
        Program p = new Program();
        while(true)
        {
            p.MyEvent += (o, e) => Console.WriteLine("Hello!");

            Console.ReadLine();
            p.Foo();
        }
    }

    void Foo()
    {
        MyEvent(this, EventArgs.Empty);
    }
}

And the output as I press 'Enter' repeatedly is

Hello!

Hello!
Hello!

Hello!
Hello!
Hello!

Hello!
Hello!
Hello!
Hello!

...and so forth. I could add the line

p.MyEvent -= (o, e) => Console.WriteLine("Hello!");

after p.Foo() but of course it has no effect because I'm removing an entirely different anonymous delegate.

So what's the deal with this? Is there any way of removing these anonymous delegates at all? What are the implications for, say, an asynchronous Silverlight application where I'm pulling data using expressions like

_myDataContext.Load(myQuery, loadOperation =>
    {
        // do stuff with the data here
    }, null);

? I assume that these kinds of callbacks aren't implemented using events, but of course it's impossible(?) to tell.

Are anonymous delegates dangerous if not carefully accounted for?

2

There are 2 answers

0
Tomas Petricek On BEST ANSWER

There is no (easy) way to remove delegates that you didn't first assing to any variable. It doesn't really matter whether they're anonymous or not. You can assign anonymous delegate to a variable and remove it later:

EventHandler eh = (src, e) => Console.WriteLine("Hello");
form.Click += eh; 
// At some later point
form.Click -= eh;

Similarly, there is no (easy) way to remove delegate if you register it using:

form.Click += new EventHandler(foo);

The problem with events is that they are only garbage collected when the object that they're attached to is garbage collected (even if the target object that they work with is not referenced from any other part of program and so they cannot do any useful work).

This can be solved using weak events. Instead of removing them explicitly, you use some mechanims that allows GC to deal with them automatically.

0
antsyawn On

It will never be automatically removed from the event.

If you want to unsubscribe an anonymous delegate, check out this question:

Unsubscribe anonymous method in C#