Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do you need to "unwire" an anonymous function/lambda

My understanding is that any event handlers wired up in C# need to be unwired as such.

Object myObject = new Object();
myObject.Event += EventHandler; //Wired
myObject.Event -= EventHandler; //Unwired

But do you need to unwire the following code? and if so, how?

Object myObject = new Object();
myObject.Event += (object sender, EventArgs e) => { }; //Wired
myObject.Event -= ????? //Unwire? How?

My assumption is no?

like image 815
Maxim Gershkovich Avatar asked Jun 09 '11 10:06

Maxim Gershkovich


3 Answers

Yes, you need to (*) and you need to do it like this:

Object myObject = new Object();
EventHandler handler = (object sender, EventArgs e) => { };
myObject.Event += handler; //Wired
myObject.Event -= handler; //Unwired

See here for an explanation.

(*)
You don't need to do it because of garbage collection. You need to do it, if you don't want the event to call your handler any more.

UPDATE:
To clarify a bit:
The only reason, why you want to unwire an event handler is that the object defining the event handler can be garbage collected.
Think about the following example:

  • You have a class PowerSource with an event BlackOut.
  • You have a class LightBulb that will be on, as long as there is power. It has a method ConnectToPowerSource. This method subscribes to the BlackOut event of the supplied PowerSource.
  • You have a collection that contains the light bulbs

Now, simply removing a light bulb from the list will not make it get garbage collected, because the PowerSource is still holding a reference to the LightBulb instance in its BlackOut event. Only after unregistering the LightBulb from the BlackOut event will make the LightBulb get garbage collected.

like image 68
Daniel Hilgarth Avatar answered Nov 11 '22 22:11

Daniel Hilgarth


Yes, you do have to. Because an event is a strong reference, your event handler will continue to be invoked.

You can remove it as follows:

EventHandler handler = (s,e) => { DoSomething(); }
myObject.Event += handler; 
myObject.Event -= handler; 
like image 34
ColinE Avatar answered Nov 11 '22 23:11

ColinE


Object myObject = new Object();
EventHandler h = (object sender, EventArgs e) => { }; //Wired
myObject.Event += h;
myObject.Event -= h;

Or, to unwire in the handler:

Object myObject = new Object();
EventHandler h = null; //need to declare h to use it in the following line
//compiler/resharper will complain about modified closure
h = (object sender, EventArgs e) => { myObject.Event-=h; };
myObject.Event += h;
like image 1
spender Avatar answered Nov 11 '22 22:11

spender