Z. Margeta

I was under the impression that the event handlers of odjects that go out of scope are automatically removed from their respective events, which does not happen in the following case.

I have a static object that exposes some events. There is also another object derived from Form, which holds a Developer Express control (not sure if it matters), and it subscribes to the static object's events. Now comes the strange stuff. The first time the form is run, everything works great, but after the form is closed (and goes out of scope), and then opened again things don't work as expected. It took me a while to figure out what was going on, but I finally figured out thet somehow after the form is closed the event handlers don't get removed from the static object's events (delegates). After I added a manual removal of the event handlers in the form's Dispose method, everything worked as expected.

So, my question is the following. Do the event handlers really get removed from their respective events after the object goes out of scope, or this somehow does not apply to static objects ( !), or it has something to do with the mentioned control, or it is a bug in the compiler


Re: Visual C# Language Unsubscribe from events

Alan M.

I have never dealt with this before... but I do know one thing (at least I think)

Your object with events... if it has a delegate that refers to your form. Then basically your form still has a reference to it through your static object. Basically.. I think your static object still has a reference to your form (through the event listener) and then your form wouldn't be garbage collected like you think it would.

I'd be interested to know if this is correct though, anyone else

Re: Visual C# Language Unsubscribe from events

Z. Margeta

Yes, but this shouldn't be happening. The thing is that the static object exposes events that fire when data that the control on the form displays changes. Static object (or any other object for that matter) doesn't have any references to the form object (unless thru the delegates), so it should go out of scope after it is closed. Nevertheless after closing the form, and re-opening it, the event handler gets called twice, so the code that deals with the Developer Express control throws an exception, since it runs on the "old" control. Maybe the Developer Express control doesn't clean up properly, I don't know. All I know is that after I add manual removal of the event handlers in the Dispose method of the control that contains the Developer Express control and is in turn contained in the form object (hope I dind't lose you here), everything works fine. So I wonder if I should do this manual removal for every object that subscribes to an other object's events.

Re: Visual C# Language Unsubscribe from events

Peter Ritchie

In general subscribing to an event does not root the object being subscribed to. But, there are circumstances where this can happen. It's always best to unsubscribe your events as quickly as possible. While this generally doesn't avoid memory leaks, it allows your objects to be collected as soon as possible.

Re: Visual C# Language Unsubscribe from events

Oren Novotny

What you're describing is a need for Weak Event Handler's. The thing to keep in mind is that events are implemented using delegates and normally, delegates hold onto a strong reference to the target object, in this case your form. So w/o unsubscribing, you might have closed the form, but it's not going to be garbaged collection because the event publisher still maintains a strong reference.

The solution is to either unsbuscribe or to use a weak event handler. With a weak event handler, the event is stored using a weak reference instead of a strong one and the next time a GC runs after your form is closed, it'll clean up the form.

Dustin Campbell has an excellent implementation of Weak Event Hanlders; be sure to check the comments at the bottom for updates.