Event Handler Destruction

  • Thread starter Thread starter David Rogers
  • Start date Start date
D

David Rogers

When I, let's say I'm a form, register myself for an event, I use a syntax
such as:

Class1.EventName += new EventNameHandler(MyFormsEventHandler);

Somewhere in global scope, I have defined the delegate EventNameHandler:

public delegate void EventNameHandler(object source, Eventargs e);

In Class1 I have:

public static event EventNameHandler EventName;

I assume that the event EventName keeps track of all of the EventNameHandler
delegates that are register with it. But who unregisters the delegate when
my form is destroyed? Can someone please explain?

Regards,
David Rogers
 
David Rogers said:
I assume that the event EventName keeps track of all of the EventNameHandler
delegates that are register with it. But who unregisters the delegate when
my form is destroyed? Can someone please explain?

I wondered about this, and used a heap profiler (.NETProfiler?) to
investigate what was going on. Basically, my forms were not dying until I
explicitly unregistered the delegates!! If you get hold of a heap profiler
(http://www.scitech.se/memprofiler/) you can investigate this yourself. I
supppose it kinda makes sense though, the forms are being referenced by the
delegates (by way of the callback), so the form shouldn't be garbage
collected until there is nothing in memory referencing it. I can't remember
if this is still the case even the delegate is set up between the form and a
control it contains?

Tobin
 
Just to add, if want to unregister the delegate I find the best places for
adding and removing it are:

Control.OnHandleCreated

and

Control.OnHandleDestroyed

The Form class derives from Control so you can override them to do your
registering / unregistering.

Regards
Lee
 
David Rogers said:
Related question: Does the framework take care of the event handlers that
are added to controls by the designer? If not, does this mean that my child
form's button click handler is going to cause that form instance to remain
in memory even after the form is gone?

If that is the case, there must be 22 million programs out there that are
leaking memory like a sieve!

Not necessarily - it's only a memory leak if you're adding the delegate
to event *outside* the form itself. Normal forms where, say, clicking a
button triggers a label to change, don't have a memory leak - the whole
lot becomes eligible for garbage collection at the same time.
 
David,
I do not believe in this instance its a problem, as the form has a reference
to the child & the child has a reference to the form. (circular references).

When you get ride of the form only that form references the children so
every thing should go away.

If your other example, form1 had a reference to form2, you had a reference
to form1, which was keeping every thing alive.

Hope this helps
Jay

David Rogers said:
Related question: Does the framework take care of the event handlers that
are added to controls by the designer? If not, does this mean that my child
form's button click handler is going to cause that form instance to remain
in memory even after the form is gone?

If that is the case, there must be 22 million programs out there that are
leaking memory like a sieve!

David
 
Arghhhh! Of course not, the events themselves are destroyed with the form,
so there is no need to unregister the delegate instances that are registered
with those events...

Cheers!
 
Jon Skeet said:
Not necessarily - it's only a memory leak if you're adding the delegate
to event *outside* the form itself. Normal forms where, say, clicking a
button triggers a label to change, don't have a memory leak - the whole
lot becomes eligible for garbage collection at the same time.

[Kind of related comments!...]
That does make sense actually - and saves us a little effort. Still a pain
for me becuase I use a kind of MVC architecture where forms subscribe to
events in 'back end' classes. So, I always have to remember to explicitly
code the unsubscribe when the form is destroyed. Thinking about it, would it
be possible to create a deligate class that could respond to the subscribers
Disposed event? When this is fired, it could remove the object from it's
list of recipients? So then calling Form.Dispose() would automatically
unsubscribe it from any delegates it's referenced by? Does anyone know if
this is possible? I don't even know if you can create custom delegates
though!? Just thinking out loud...

Tobin
 
Back
Top