2

What is the lifetime of a lambda expression?

Here is my problem: I have a button1.Click event subscribed by a lambda expression. I don't know if I need need to unsubscribe it (which is not easy because it is anonymous)? Or I don't have to, because it is in the same lifetime of the control(button1) it is attached?

button1.Click += (s, e) => { /*Do something; */};
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Roy
  • 81
  • 3
  • 10

3 Answers3

4

Since the lambda expression is associated with the button,it will live as long as the button is not destroyed from memory.for your question

I don't know if I need need to unsubscribe it (which is not easy because it is anonymous)?

Lambda expressions can be saved to a EventHandler delegate,which gives you the option to access the lambda and unsubscribe from the event.Here is the code.

    EventHandler myEvent= (s, e) => { /*Do something; */};  
    //Subscribe
    button1.Click += myEvent;
    //Unsubscribe
    button1.Click -= myEvent;

probably the best explanation on this topic here Should I unsubscribe from events?

Community
  • 1
  • 1
Prabhu Murthy
  • 9,031
  • 5
  • 29
  • 36
  • Thanks! I think in this way, we lost the benefit of using lambda expression as event handler. That's why I'm extremely interested in the life time of lambda expression. Can you give any clue? Thanks! – Roy Sep 29 '12 at 06:17
  • There's no need to unsubscribe in this case. If you want the same event handler to be associated with the button as long as the button lives, don't worry about it. See Jon Skeet's answer in the other SO thread linked here. Only if the event handler associated with the button needs to be altered during the life-time of the button, will you have to remove your event handler manually. – Jeppe Stig Nielsen Sep 29 '12 at 06:38
4

As all normal CLR objects resulting delegate's lifetime will be defined by whatever have references to it. In your case only button1 holds the reference via Click. As result it will be propely available for garbage collection at the same time as button1. Unless there are special reasons (i.e. want to change handler to another one) you don't need to do anything special to "free" it.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • That sounds encouraging to my current solution! Thanks, Alexei. Can you give any reference of it? Really appreciate it! – Roy Sep 29 '12 at 06:20
2

You can easily retain a reference to a reference to your event handler by capturing it with a local variable.

        EventHandler click = (s, e) => { /* Do something; */ };

Then you can attach it like so:

        this.button1.Click += click;

Cleaning up can be a little more tricky because it often requires you to make a class-level variable to hold the reference to the handler. This leads to code scattered throughout your class.

However, there's a fairly easy way to handle it. Make a class-level cleanup action to capture all of you clean-up actions like so:

        private Action cleanup = () => { };

Now your code to attach an event handler can be located nicely in a single method like so:

        EventHandler click = (s, e) => { /* Do something; */ };
        this.button1.Click += click;
        cleanup += () => this.button1.Click -= click;

When you are done with your form you can just do the clean-up very quickly like this:

        cleanup();

The cool thing is that you can add all sorts of clean-up code to this action variable.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172