471,337 Members | 1,102 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

Given an 'event', how do I obtain underlying delegates ?

Hi,

Various custom controls in my WinForms application register for the
'Application.Idle' event on load, and unregister on dispose. To avoid memory
leaks, it's essential that I remember to unregister on dispose.

Before my application exits, I'd like to do an 'assert' to assure myself
that there are no cases in which I've forgotten to unregister. I was under
the impression that an event is nothing more than a collection of delegates.
I therefore tried:

Debug.Assert(Application.Idle.Count==0);

This doesn't compile, however, and begs the question: Given an event
object, how do I obtain the underlying delegate collection?

Dave
Jan 18 '06 #1
12 1520
What makes you think you need to do that?

You don't.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a fish to a bicycle,
but it takes a very long time,
and the bicycle has to *want* to change.

"The One We Call 'Dave'" <gh****@englewood.com> wrote in message
news:JY********************@giganews.com...
Hi,

Various custom controls in my WinForms application register for the
'Application.Idle' event on load, and unregister on dispose. To avoid
memory leaks, it's essential that I remember to unregister on dispose.

Before my application exits, I'd like to do an 'assert' to assure
myself that there are no cases in which I've forgotten to unregister. I
was under the impression that an event is nothing more than a collection
of delegates. I therefore tried:

Debug.Assert(Application.Idle.Count==0);

This doesn't compile, however, and begs the question: Given an event
object, how do I obtain the underlying delegate collection?

Dave

Jan 18 '06 #2
"The One We Call 'Dave'" <gh****@englewood.com> wrote in message
news:JY********************@giganews.com...
Given an event object, how do I obtain the underlying delegate collection?


I think something along these lines:

// Number of subscribers to the event:
int n = Idle.GetInvocationList().Length;

- OR -

// Get at each subscriber:
System.Delegate[] DelegateList = Idle.GetInvocationList();
foreach (IdleDelegate Delegate in DelegateList) {
...
}
-- Alan
Jan 18 '06 #3
> "The One We Call 'Dave'" <gh****@englewood.com> wrote in message
news:JY********************@giganews.com...
Given an event object, how do I obtain the underlying delegate
collection?

I think something along these lines:

// Number of subscribers to the event:
int n = Idle.GetInvocationList().Length;
- OR -

// Get at each subscriber:
System.Delegate[] DelegateList = Idle.GetInvocationList();
foreach (IdleDelegate Delegate in DelegateList) {
...
}


Both of those will result in compiler error "The event...can only appear
on the left hand side of += or -=";

This is a fun one and I'm experimenting with it right now.

Chris
Jan 18 '06 #4
> What makes you think you need to do that?

You don't.


You most certainly do. 'Application.Idle' is a static event. If you fail
to unregister, the reference will be held in the event collection until the
Application terminates. This constitutes a memory leak. Just to confirm, I
looked up the event in MSDN and found this excerpt:

Because this is a static event, you must detach any event handlers
attached to this event in the ApplicationExit event. If you do not detach
these handlers, they will remain attached to the event and continue to
consume memory.
David
Jan 18 '06 #5
> Various custom controls in my WinForms application register for the
'Application.Idle' event on load, and unregister on dispose. To avoid memory
leaks, it's essential that I remember to unregister on dispose.
If the control is disposed of while the app still runs, yes.
Before my application exits, I'd like to do an 'assert' to assure myself
that there are no cases in which I've forgotten to unregister. I was under
the impression that an event is nothing more than a collection of delegates.
I therefore tried:
When your app exits, the Application.Idle event goes with it.
Application.Idle is 'just' WinForms' way of multiplexing the idle
proc. There should be no consequences of terminating an app with a
populated Application.Idle.
Debug.Assert(Application.Idle.Count==0);

This doesn't compile, however, and begs the question: Given an event
object, how do I obtain the underlying delegate collection?


So far as I know (and I just yesterday found how far from
comprehensive my understanding of events is) you don't: the only
things you can do with another class's event is += and -= it.

--
<http://www.midnightbeach.com>
Jan 18 '06 #6
> I think something along these lines:

// Number of subscribers to the event:
int n = Idle.GetInvocationList().Length;


Thanks for the reply.

I had a similar thought, but I get the following compilation error:

Error 1 The event 'System.Windows.Forms.Application.Idle' can only appear on
the left hand side of += or -=

David
Jan 18 '06 #7
>> What makes you think you need to do that?

You don't.

You most certainly do. 'Application.Idle' is a static event. If
you fail to unregister, the reference will be held in the event
collection until the Application terminates. This constitutes a memory
leak. Just to confirm, I looked up the event in MSDN and found this
excerpt:

Because this is a static event, you must detach any event handlers
attached to this event in the ApplicationExit event. If you do not
detach
these handlers, they will remain attached to the event and continue to
consume memory.
David


Take a look at this Dave.

I just tested it and it's golden!

http://tinyurl.com/ao252
Jan 18 '06 #8
> When your app exits, the Application.Idle event goes with it.
Application.Idle is 'just' WinForms' way of multiplexing the idle
proc. There should be no consequences of terminating an app with a
populated Application.Idle.


Ah, now I see why Kevin made the comment that he did. I didn't express
myself clearly (sorry kevin).

I didn't mean to imply that there were negative consequences of terminating
the app with a bunch of Application.Idle callbacks in place. The only reason
I want to perform the assert is to confirm with myself that I'm not
forgetting to unregster these handlers.

My WinForms app will be active for weeks at a time. Many controls will be
created and subsequently disposed during that period. If I forget to
unregister these handlers, the effect of the memory leak will build up over
the lifetime of the application session. I thought that running an assert
just prior to exit would be a clever way to determine during the development
phase whether I was failing to clean up any of these handlers.

David
Jan 18 '06 #9
> Take a look at this Dave.

I just tested it and it's golden!

http://tinyurl.com/ao252


Oh my! Well, I certainly wouldn't have guessed approach that on my own. :)
Thanks, I'll try it.
Jan 19 '06 #10
>> Take a look at this Dave.

I just tested it and it's golden!

http://tinyurl.com/ao252

Oh my! Well, I certainly wouldn't have guessed approach that on my
own. :) Thanks, I'll try it.


After screwing with this, trying to find an answer (before the googlin'),
this was definately where I was heading. My stuff was way uglier though.

That class I linked is a keeper methinks.
Jan 19 '06 #11
Dave,

I am curious why you want to do this before your application exits.
From a cleanup point of view, the app domain is going to be torn down,
meaning your objects are going to be collected. On top of that, your
process is going to disappear. Given that event handlers (methods on
objects) are not resources that need to be reclaimed at the risk of
something detrimental, it doesn't seem to be a big deal to me, at the time
your app shuts down.

The other concerns you have are valid, about your class/control
unsubscribing to the Idle event. However, your assertion is wrong, because
you assume that your classes are the only ones subscribing. What if there
are elements of the framework that subscribe, and are ok with doing so for
the lifetime of the app? What do you do then?

The best you can do is make sure your classes implement IDisposable, to
indicate that lifetime management needs to be a consideration when using the
class, and make sure to unsubscribe when done.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"The One We Call 'Dave'" <gh****@englewood.com> wrote in message
news:JY********************@giganews.com...
Hi,

Various custom controls in my WinForms application register for the
'Application.Idle' event on load, and unregister on dispose. To avoid
memory leaks, it's essential that I remember to unregister on dispose.

Before my application exits, I'd like to do an 'assert' to assure
myself that there are no cases in which I've forgotten to unregister. I
was under the impression that an event is nothing more than a collection
of delegates. I therefore tried:

Debug.Assert(Application.Idle.Count==0);

This doesn't compile, however, and begs the question: Given an event
object, how do I obtain the underlying delegate collection?

Dave

Jan 19 '06 #12
> Ah, now I see why Kevin made the comment that he did. I didn't express
myself clearly (sorry kevin).


No need to apologize. I am well aware of my communication difficulties. I'm
sure it was as much my fault as yours!

In any case, I see you've straightened it out. All's well that ends well!

--

Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a fish to a bicycle,
but it takes a very long time,
and the bicycle has to *want* to change.

"The One We Call 'Dave'" <gh****@englewood.com> wrote in message
news:48********************@giganews.com...
When your app exits, the Application.Idle event goes with it.
Application.Idle is 'just' WinForms' way of multiplexing the idle
proc. There should be no consequences of terminating an app with a
populated Application.Idle.


Ah, now I see why Kevin made the comment that he did. I didn't express
myself clearly (sorry kevin).

I didn't mean to imply that there were negative consequences of
terminating the app with a bunch of Application.Idle callbacks in place.
The only reason I want to perform the assert is to confirm with myself
that I'm not forgetting to unregster these handlers.

My WinForms app will be active for weeks at a time. Many controls will be
created and subsequently disposed during that period. If I forget to
unregister these handlers, the effect of the memory leak will build up
over the lifetime of the application session. I thought that running an
assert just prior to exit would be a clever way to determine during the
development phase whether I was failing to clean up any of these handlers.

David

Jan 19 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Ian Richardson | last post: by
2 posts views Thread by Lore Leuneog | last post: by
6 posts views Thread by Ondrej Sevecek | last post: by
3 posts views Thread by Bob | last post: by
3 posts views Thread by Chua Wen Ching | last post: by
1 post views Thread by MuZZy | last post: by

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.