473,626 Members | 3,216 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Cleaning Up Event Handlers

Hello,

I'm aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.

Therefore, I've been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).

Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAu dioFile.Checked Changed += new
System.EventHan dler(this.menuI temAudioFile_Ch eckedChanged);

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that's the case, why doesn't the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?

Or maybe I'm totally misunderstandin g the issue!

Thanks!

Jun 1 '07 #1
13 3923
In the case that you show, where you attach to the CheckChanged event,
it doesn't matter, because it is a circular reference, which GC will pick
up. The form holds a reference to the control, which holds a reference to
the form indirectly through the event.

The only time that you have to worry about this is when you subscribe to
an event on another class, and you don't want that reference to prevent you
from disposing yourself.

A good example of this is when you have a form that is attached to
another form's Closed event. If the the form that is subscribed to the
event closes, the object is still in memory (although Disposed) because of
the subscription to the Closed event on the other form.

However, if all the events and subscriptions are self-contained, in the
sense that they are all on the same form/control and only to each other,
then you don't have to worry about this. It's when your form subscribes to
an event outside of itself (or any class, not just forms for that matter)
that you have to worry.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"dmeglio" <dm*****@gmail. comwrote in message
news:11******** *************@q 66g2000hsg.goog legroups.com...
Hello,

I'm aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.

Therefore, I've been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).

Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAu dioFile.Checked Changed += new
System.EventHan dler(this.menuI temAudioFile_Ch eckedChanged);

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that's the case, why doesn't the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?

Or maybe I'm totally misunderstandin g the issue!

Thanks!

Jun 1 '07 #2
On Jun 1, 1:15 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guar d.caspershouse. comwrote:
In the case that you show, where you attach to the CheckChanged event,
it doesn't matter, because it is a circular reference, which GC will pick
up. The form holds a reference to the control, which holds a reference to
the form indirectly through the event.

The only time that you have to worry about this is when you subscribe to
an event on another class, and you don't want that reference to prevent you
from disposing yourself.

A good example of this is when you have a form that is attached to
another form's Closed event. If the the form that is subscribed to the
event closes, the object is still in memory (although Disposed) because of
the subscription to the Closed event on the other form.

However, if all the events and subscriptions are self-contained, in the
sense that they are all on the same form/control and only to each other,
then you don't have to worry about this. It's when your form subscribes to
an event outside of itself (or any class, not just forms for that matter)
that you have to worry.

--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard .caspershouse.c om

"dmeglio" <dmeg...@gmail. comwrote in message

news:11******** *************@q 66g2000hsg.goog legroups.com...
Hello,
I'm aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.
Therefore, I've been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).
Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAu dioFile.Checked Changed += new
System.EventHan dler(this.menuI temAudioFile_Ch eckedChanged);
Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that's the case, why doesn't the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?
Or maybe I'm totally misunderstandin g the issue!
Thanks!- Hide quoted text -

- Show quoted text -
So essentially, if an object subscribes to an event of one of it's
children (e.g. an encapsulated object), I'm ok?

Jun 1 '07 #3
On Fri, 01 Jun 2007 09:36:19 -0700, dmeglio <dm*****@gmail. comwrote:
I'm aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.

Therefore, I've been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).
I think you're doing something you don't need to do. See below.
Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAu dioFile.Checked Changed += new
System.EventHan dler(this.menuI temAudioFile_Ch eckedChanged);

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that's the case, why doesn't the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?
If the class containing the event cannot be collected then any other class
that has subscribed to the event also cannot be collected. This does mean
that if you've got a class that's subscribed to an event but does not
unsubscribe before you try to get rid of it (you have no other explicit
references to it), the class won't be collected. However, if that happens
and then the class with the event is also left unreferenced, then neither
the class with the event or the class subscribed to its event will be
reachable and so both can be collected at that point.

Now, all that said, in your particular example you appear to be dealing
with code in which the class containing the instance with the event is the
one with the handler. So presumably you're not going to be discarding
that class until you've also discarded the instance with the event, and
then everything gets cleaned up fine.

This is the situation with Designer-created forms and controls, which is
why there's no need to do any sort of IDispose stuff to clean things up.
In fact, I can't think of any situation related to event subscription
which would require you to implement a Dispose method. Events are
managed, subscribers are managed, so the GC knows all about them and
should always do the right thing.

Pete
Jun 1 '07 #4
Yes, you are ok. It creates a circular reference, and when all
references to those individual objects outside of each other are released,
your object will be eligible for GC.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"dmeglio" <dm*****@gmail. comwrote in message
news:11******** **************@ q69g2000hsb.goo glegroups.com.. .
On Jun 1, 1:15 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guar d.caspershouse. comwrote:
> In the case that you show, where you attach to the CheckChanged
event,
it doesn't matter, because it is a circular reference, which GC will pick
up. The form holds a reference to the control, which holds a reference
to
the form indirectly through the event.

The only time that you have to worry about this is when you subscribe
to
an event on another class, and you don't want that reference to prevent
you
from disposing yourself.

A good example of this is when you have a form that is attached to
another form's Closed event. If the the form that is subscribed to the
event closes, the object is still in memory (although Disposed) because
of
the subscription to the Closed event on the other form.

However, if all the events and subscriptions are self-contained, in
the
sense that they are all on the same form/control and only to each other,
then you don't have to worry about this. It's when your form subscribes
to
an event outside of itself (or any class, not just forms for that matter)
that you have to worry.

--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard .caspershouse.c om

"dmeglio" <dmeg...@gmail. comwrote in message

news:11******* **************@ q66g2000hsg.goo glegroups.com.. .
Hello,
I'm aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.
Therefore, I've been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).
Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAu dioFile.Checked Changed += new
System.EventHan dler(this.menuI temAudioFile_Ch eckedChanged);
Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that's the case, why doesn't the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?
Or maybe I'm totally misunderstandin g the issue!
Thanks!- Hide quoted text -

- Show quoted text -

So essentially, if an object subscribes to an event of one of it's
children (e.g. an encapsulated object), I'm ok?

Jun 1 '07 #5
On Jun 1, 1:42 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guar d.caspershouse. comwrote:
Yes, you are ok. It creates a circular reference, and when all
references to those individual objects outside of each other are released,
your object will be eligible for GC.
One more follow up... Say I have Form1. On Form1 is Control1. Now lets
say, every 20 seconds I change Control1 to something else (very
hypothetical, but some pseudocode might help):
every_20_second s()
{
this.Control1.S omeEvent += new MyHandler
this.Control1 = new Control1(someNe wValue);
}

In this instance, when the new Control1 is executed, the "old"
Control1 still exists because I have an event reference to it,
correct? Now it will be disposed when Form1 is disposed, but Form1 is
my main app window, therefore, if I want the "old" Control1s' memory
to be freed, I need to have a -= before I allocate a new Control1?
Hope that made sense :)

Jun 1 '07 #6
You have it backwards.

When you do this:

this.Control1.S omeEvent += new MyHandler

Then Control1 has a reference to the form (or whatever object has the
method that MyHandler is going to execute). When you do this:

this.Control1 = new Control1(someNe wValue);

Then the old Control1 ends up being eligible for garbage collection
(make sure you call Dispose on the old Control1 before you assign a new
control to it). It still has a reference to your form because it has the
delegate, but that doesn't make it eligible for GC, as your form is still
rooted. The form doesn't have a reference to the control anymore.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"dmeglio" <dm*****@gmail. comwrote in message
news:11******** *************@g 4g2000hsf.googl egroups.com...
On Jun 1, 1:42 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guar d.caspershouse. comwrote:
> Yes, you are ok. It creates a circular reference, and when all
references to those individual objects outside of each other are
released,
your object will be eligible for GC.

One more follow up... Say I have Form1. On Form1 is Control1. Now lets
say, every 20 seconds I change Control1 to something else (very
hypothetical, but some pseudocode might help):
every_20_second s()
{
this.Control1.S omeEvent += new MyHandler
this.Control1 = new Control1(someNe wValue);
}

In this instance, when the new Control1 is executed, the "old"
Control1 still exists because I have an event reference to it,
correct? Now it will be disposed when Form1 is disposed, but Form1 is
my main app window, therefore, if I want the "old" Control1s' memory
to be freed, I need to have a -= before I allocate a new Control1?
Hope that made sense :)

Jun 1 '07 #7
On Fri, 01 Jun 2007 10:51:45 -0700, dmeglio <dm*****@gmail. comwrote:
[...]
In this instance, when the new Control1 is executed, the "old"
Control1 still exists because I have an event reference to it,
correct? Now it will be disposed when Form1 is disposed, but Form1 is
my main app window, therefore, if I want the "old" Control1s' memory
to be freed, I need to have a -= before I allocate a new Control1?
That would be a pretty poor design, destroying and recreating controls on
the fly like that. But yes, assuming you find that design necessary, then
if the form doesn't unsubscribe from the event, the control you've tried
to discard will remain in memory. One hopes that it has no way to fire
its event at that point, but if it should do so, then you will even find
your form's event handler getting called.

Note that even in this case though, implementing Dispose() in the
subscriber to have it unsubscribe doesn't get you anything, because the
subscriber isn't the thing that's being discarded. You need to explicitly
unsubscribe your form's handler from the control before you discard the
control (as you guessed).

Pete
Jun 1 '07 #8
Peter,

The control will not remain in memory. If the form owns the control,
and the control has a reference back to the form indirectly through an event
handler, then when you release the reference on the control, the control is
eligible for GC, the form has no ties to it anymore.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Peter Duniho" <Np*********@nn owslpianmk.comw rote in message
news:op******** *******@petes-computer.local. ..
On Fri, 01 Jun 2007 10:51:45 -0700, dmeglio <dm*****@gmail. comwrote:
[...]
In this instance, when the new Control1 is executed, the "old"
Control1 still exists because I have an event reference to it,
correct? Now it will be disposed when Form1 is disposed, but Form1 is
my main app window, therefore, if I want the "old" Control1s' memory
to be freed, I need to have a -= before I allocate a new Control1?
That would be a pretty poor design, destroying and recreating controls on
the fly like that. But yes, assuming you find that design necessary, then
if the form doesn't unsubscribe from the event, the control you've tried
to discard will remain in memory. One hopes that it has no way to fire
its event at that point, but if it should do so, then you will even find
your form's event handler getting called.

Note that even in this case though, implementing Dispose() in the
subscriber to have it unsubscribe doesn't get you anything, because the
subscriber isn't the thing that's being discarded. You need to explicitly
unsubscribe your form's handler from the control before you discard the
control (as you guessed).

Pete
Jun 1 '07 #9
On Fri, 01 Jun 2007 11:17:07 -0700, Nicholas Paldino [.NET/C# MVP]
<mv*@spam.guard .caspershouse.c omwrote:
The control will not remain in memory. If the form owns the control,
and the control has a reference back to the form indirectly through an
event
handler, then when you release the reference on the control, the control
is
eligible for GC, the form has no ties to it anymore.
Right. I knew that. :)

Sorry for any confusion...my post was obviously ill-conceived. :)

Pete
Jun 1 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
3578
by: tony kulik | last post by:
This code works fine in ie and opera but not at all in Mozilla. Anybody got a clue as to how to get it right? <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <script language="JavaScript" type="text/javascript"> function show(that) { if (box.style.visibility=='hidden') { that.style.visibility = 'visible'}; }
6
1783
by: Charles Law | last post by:
I have a class, which implements an interface. Let's say, that the interface looks something like Public Interface IEventSinks Sub ValueChanged(sender As Object, e As ValueChangedEventArgs) Sub StateUpdated(sender As Object, e As StateUpdatedEventArgs) End Interface In practice, the interface contains many more event handlers like this, but you get the picture.
13
3498
by: Charles Law | last post by:
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my question about removing event handlers. > http://www.vbinfozine.com/t_bindevt.shtml Following on from that post, the following issues still exist. The article shows how to find methods on a receiver that match the pattern OnXXXX given the sender. It loops through the sender events and tries to get methods from the receiver that match the pattern. For each one...
5
3874
by: Amit | last post by:
Hello! Is it possible to find how many event handlers an event has at runtime? How about finding whether or not an event has event handlers? In C# you can compare the event with null to check if it has event handlers, but I can't find the equivalent in VB. Thanks Amit
7
1708
by: Michael D. Ober | last post by:
Is there anyway to raise an event from a class and require that any program using that class (not just inheritance) have an event handler for specific events in the class? In my case, some events don't need to be handled, but some must be handled by the program that uses the class. I'm looking for something along the lines of Class MyClass Event OptionalEvent(parms) Event RequiredEvent(parms)
16
2503
by: Hamed | last post by:
Hello I am developing a utility to be reused in other programs. It I have an object of type Control (a TextBox, ComboBox, etc.) that other programmers use it in applications. they may set some of properties or assign event handlers. I need to be able to clone the manipulated control at runtime. I could use the Clone method of some objects (like Font, Style, String,
14
8612
by: Hamed | last post by:
Hello It seems that I should implement ICloneable to implement my own clone object. the critical point for me is to make a control object based on another control object that all of its event handlers are set like the old one. Is there a way to do this job? For example, is there a way to use EventInfo object to get all event handlers of the old control in runtime and set my new cloned control events to the event handlers of the old...
6
2115
by: Jake K | last post by:
Where is the best place to define event handlers? I need to define event handlers for a COM object referenced in my project and am doing so in the fowm load. Is this the best place?
5
3070
by: Lloyd Sheen | last post by:
Is there a way to get the event handlers such that I can cache the info about handlers for a particular control, remove the handlers, do some code and restore the cached event handlers in VB.NET (2008). I would rather do things this way than having to have a boolean flag to indicated to the handler to exit right away. Psuedo code: CacheHandlers(control)
6
2015
by: Tony Johansson | last post by:
Hello! I know it's possible to have several event handler for a single event but I can't see any point using several event handler for this. I'm probably wrong so can anybody tell me what advantage it might give using several event handler for a single event.
0
8707
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8641
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7199
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6125
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5575
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4202
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2628
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1812
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1512
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.