By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,143 Members | 1,919 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,143 IT Pros & Developers. It's quick & easy.

VB.NET events creates a hidden delegate, but how do I access it?

P: n/a
I'm working with VB.NET events and I want a way to disconnect all the
handlers of an event. I want to do this in the object that is the
source of the event. This is slightly tricky in VB.Net as the eventing
code is slightly hidden.

when you use events in Vb.Net you type this:
<code>
Public event MyEvent()
</code>

what the compiler adds for you is some hiddent things something like:
<code>
Public Delegate MyEventEventHandler()

Public MyEventEvent as MyEventEventHandler
</code>

Plus you get some extra hidden properties for editing the list of
handlers on the event.

I want to loop through the handlers of each event and remove them so
when I want to dispose of the object there are no references keeping it
alive. This is not so tough, I think. If you do this
<code>
Me.MyEventEvent.GetInvocationList()
</code>
you get a list of the delegates that have been combined (i.e., a list
of the added event handlers), so you can disconnect them one at a time.
This code works in the debugger, but if you do something like this
<code>
Me.GetType().GetMembers()
</code>
you get a huge list of stuff that includes MyEvent but does NOT include
MyEventEvent or MyEventEventHandler. Howver, if you just write the code
to do it, knowing the event name, it all works.

What I want is a way to access these generated/hidden/implict event
delegates by using reflection.I've seen some people say that they were
doing the same thing and found out how, but they didn't post the code!

Any pointers (ha!)?

sam

May 26 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Sam,

Any reason that you don't use RemoveHandler?

In VBNet handling events is very easy, it don't need the difficult ways from
C#

http://msdn2.microsoft.com/en-us/ms172928.aspx

Cor

"sam.m.gardiner" <sa************@gmail.com> schreef in bericht
news:11**********************@j33g2000cwa.googlegr oups.com...
I'm working with VB.NET events and I want a way to disconnect all the
handlers of an event. I want to do this in the object that is the
source of the event. This is slightly tricky in VB.Net as the eventing
code is slightly hidden.

when you use events in Vb.Net you type this:
<code>
Public event MyEvent()
</code>

what the compiler adds for you is some hiddent things something like:
<code>
Public Delegate MyEventEventHandler()

Public MyEventEvent as MyEventEventHandler
</code>

Plus you get some extra hidden properties for editing the list of
handlers on the event.

I want to loop through the handlers of each event and remove them so
when I want to dispose of the object there are no references keeping it
alive. This is not so tough, I think. If you do this
<code>
Me.MyEventEvent.GetInvocationList()
</code>
you get a list of the delegates that have been combined (i.e., a list
of the added event handlers), so you can disconnect them one at a time.
This code works in the debugger, but if you do something like this
<code>
Me.GetType().GetMembers()
</code>
you get a huge list of stuff that includes MyEvent but does NOT include
MyEventEvent or MyEventEventHandler. Howver, if you just write the code
to do it, knowing the event name, it all works.

What I want is a way to access these generated/hidden/implict event
delegates by using reflection.I've seen some people say that they were
doing the same thing and found out how, but they didn't post the code!

Any pointers (ha!)?

sam

May 27 '06 #2

P: n/a
On 2006-05-27, Cor Ligthert [MVP] <no************@planet.nl> wrote:
Sam,

Any reason that you don't use RemoveHandler?
And where would you get the [Delegate] parameter to RemoveHandler?
Remember, he's trying to do this from within the class that declared the
event. IAW, from the Publisher end of things, not the Subscriber end of
things.
In VBNet handling events is very easy, it don't need the difficult ways from
C#

http://msdn2.microsoft.com/en-us/ms172928.aspx

Cor

"sam.m.gardiner" <sa************@gmail.com> schreef in bericht
news:11**********************@j33g2000cwa.googlegr oups.com...
I'm working with VB.NET events and I want a way to disconnect all the
handlers of an event. I want to do this in the object that is the
source of the event. This is slightly tricky in VB.Net as the eventing
code is slightly hidden.

when you use events in Vb.Net you type this:
<code>
Public event MyEvent()
</code>

what the compiler adds for you is some hiddent things something like:
<code>
Public Delegate MyEventEventHandler()

Public MyEventEvent as MyEventEventHandler
</code>

Plus you get some extra hidden properties for editing the list of
handlers on the event.

I want to loop through the handlers of each event and remove them so
when I want to dispose of the object there are no references keeping it
alive. This is not so tough, I think. If you do this
<code>
Me.MyEventEvent.GetInvocationList()
</code>
you get a list of the delegates that have been combined (i.e., a list
of the added event handlers), so you can disconnect them one at a time.
This code works in the debugger, but if you do something like this
<code>
Me.GetType().GetMembers()
</code>
you get a huge list of stuff that includes MyEvent but does NOT include
MyEventEvent or MyEventEventHandler. Howver, if you just write the code
to do it, knowing the event name, it all works.

What I want is a way to access these generated/hidden/implict event
delegates by using reflection.I've seen some people say that they were
doing the same thing and found out how, but they didn't post the code!

Any pointers (ha!)?

sam


May 27 '06 #3

P: n/a
On 2006-05-26, sam.m.gardiner <sa************@gmail.com> wrote:
I'm working with VB.NET events and I want a way to disconnect all the
handlers of an event. I want to do this in the object that is the
source of the event. This is slightly tricky in VB.Net as the eventing
code is slightly hidden.

when you use events in Vb.Net you type this:
<code>
Public event MyEvent()
</code>

what the compiler adds for you is some hiddent things something like:
<code>
Public Delegate MyEventEventHandler()

Public MyEventEvent as MyEventEventHandler
</code>

Plus you get some extra hidden properties for editing the list of
handlers on the event.

I want to loop through the handlers of each event and remove them so
when I want to dispose of the object there are no references keeping it
alive. This is not so tough, I think. If you do this
<code>
Me.MyEventEvent.GetInvocationList()
</code>
you get a list of the delegates that have been combined (i.e., a list
of the added event handlers), so you can disconnect them one at a time.
This code works in the debugger, but if you do something like this
<code>
Me.GetType().GetMembers()
</code>
you get a huge list of stuff that includes MyEvent but does NOT include
MyEventEvent or MyEventEventHandler. Howver, if you just write the code
to do it, knowing the event name, it all works.

You have to pass appropriate binding flags to get private members of a
class. IAW

Me.GetType().GetMembers(Reflection.BindingFlags.No nPublic Or _
Reflection.BindingFlags.Instance)
This will get you MyEventEvent, but MyEventEventHandler is a type, not a
member, so if you need it you'll need to do something different.

OTOH, I'm not really sure why using the name of the delegate is such a
bad thing. Are you trying to do this generically, or are you just
trying to stay away from undocumented aspects of the language.

What I want is a way to access these generated/hidden/implict event
delegates by using reflection.I've seen some people say that they were
doing the same thing and found out how, but they didn't post the code!

Any pointers (ha!)?

sam

May 27 '06 #4

P: n/a
Hello, Sam,

Does this link provide any assistance with your problem?

http://www.devx.com/vb2themax/Article/19835/1763

Cheers,
Randy
sam.m.gardiner wrote:
I'm working with VB.NET events and I want a way to disconnect all the
handlers of an event. I want to do this in the object that is the
source of the event. This is slightly tricky in VB.Net as the eventing
code is slightly hidden.

when you use events in Vb.Net you type this:
<code>
Public event MyEvent()
</code>

what the compiler adds for you is some hiddent things something like:
<code>
Public Delegate MyEventEventHandler()

Public MyEventEvent as MyEventEventHandler
</code>

Plus you get some extra hidden properties for editing the list of
handlers on the event.

I want to loop through the handlers of each event and remove them so
when I want to dispose of the object there are no references keeping it
alive. This is not so tough, I think. If you do this
<code>
Me.MyEventEvent.GetInvocationList()
</code>
you get a list of the delegates that have been combined (i.e., a list
of the added event handlers), so you can disconnect them one at a time.
This code works in the debugger, but if you do something like this
<code>
Me.GetType().GetMembers()
</code>
you get a huge list of stuff that includes MyEvent but does NOT include
MyEventEvent or MyEventEventHandler. Howver, if you just write the code
to do it, knowing the event name, it all works.

What I want is a way to access these generated/hidden/implict event
delegates by using reflection.I've seen some people say that they were
doing the same thing and found out how, but they didn't post the code!

Any pointers (ha!)?

sam

May 29 '06 #5

P: n/a
Sam,
Are you the author of the source class?

Are you using .NET 2.0?

If you are the author of the source class & are using .NET 2.0 then I would
recommend using custom events.

Private m_myEvent As EventHandler

Public Custom Event MyEvent As EventHandler
AddHandler(ByVal value As EventHandler)
m_myEvent = DirectCast([Delegate].Combine(m_myEvent, value),
EventHandler)
End AddHandler

RemoveHandler(ByVal value As EventHandler)
m_myEvent = DirectCast([Delegate].Remove(m_myEvent, value),
EventHandler)
End RemoveHandler

RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
m_myEvent.Invoke(sender, e)
End RaiseEvent
End Event

I would consider basing the above on the EventHandlerList

Imports System.ComponentModel

Private m_events As EventHandlerList

Protected ReadOnly Property Events() As EventHandlerList
Get
If m_events Is Nothing Then
m_events = New EventHandlerList
End If
Return m_events
End Get
End Property

Private ReadOnly MyEventKey As Object = New Object()

Public Custom Event MyEvent As EventHandler
AddHandler(ByVal value As EventHandler)
Events.AddHandler(MyEventKey, value)
End AddHandler

RemoveHandler(ByVal value As EventHandler)
Events.RemoveHandler(MyEventKey, value)
End RemoveHandler

RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
Dim handers As EventHandler = DirectCast(Events(MyEventKey),
EventHandler)
handers.Invoke(sender, e)
End RaiseEvent
End Event

Note: classes that inherit directly or indirectly from
System.ComponentModel.Component give you the Events property.

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net
"sam.m.gardiner" <sa************@gmail.com> wrote in message
news:11**********************@j33g2000cwa.googlegr oups.com...
| I'm working with VB.NET events and I want a way to disconnect all the
| handlers of an event. I want to do this in the object that is the
| source of the event. This is slightly tricky in VB.Net as the eventing
| code is slightly hidden.
|
| when you use events in Vb.Net you type this:
| <code>
| Public event MyEvent()
| </code>
|
| what the compiler adds for you is some hiddent things something like:
| <code>
| Public Delegate MyEventEventHandler()
|
| Public MyEventEvent as MyEventEventHandler
| </code>
|
| Plus you get some extra hidden properties for editing the list of
| handlers on the event.
|
| I want to loop through the handlers of each event and remove them so
| when I want to dispose of the object there are no references keeping it
| alive. This is not so tough, I think. If you do this
| <code>
| Me.MyEventEvent.GetInvocationList()
| </code>
| you get a list of the delegates that have been combined (i.e., a list
| of the added event handlers), so you can disconnect them one at a time.
| This code works in the debugger, but if you do something like this
| <code>
| Me.GetType().GetMembers()
| </code>
| you get a huge list of stuff that includes MyEvent but does NOT include
| MyEventEvent or MyEventEventHandler. Howver, if you just write the code
| to do it, knowing the event name, it all works.
|
| What I want is a way to access these generated/hidden/implict event
| delegates by using reflection.I've seen some people say that they were
| doing the same thing and found out how, but they didn't post the code!
|
| Any pointers (ha!)?
|
| sam
|
May 29 '06 #6

P: n/a
I am the author of the source class and I am not using .Net 2.

I am trying to create some code that will allow a event-raising class
to remove all of the handlers that are attached to its events. This
will prevent the handlers keeping references to the event-raising class
and allow it to be garbage collected.

I have obtained the reference to the event delegate (as david points
out, this is a nested type) but I need the reference to MyEventEvent
which is the _instance_ of this type that is contained in the class
that contains the list of handlers. Once I have this list I can run
through it and detach them all.

I started doing this a I saw some code the other day where somone had
attached to 5 different events, then had to detach from them all in
order to clean up. Seemed tedious and error prone. I wondered why
no-one had written a thing to do the detaching, then I found that it
was a wee bit tricky. Hence this thread.

Thanks for the article Randy, very informative. I'm not very up on my
IL and I haven't tried to read it yet maybe I should learn... And
david, I have tried something like this as I guessed it was private but
I may have screwed it up. I'm trying to do this without having to know
that the member ius called MyEventEvent, as this seems crappy.
Although, this is very unlikely to change, so would probably work.

If I get it running nicely I'll post it, as it should be only a few
lines.

sam

May 29 '06 #7

P: n/a
Sam,
| This
| will prevent the handlers keeping references to the event-raising class
| and allow it to be garbage collected.
The handler's don't keep a reference to the event-raising class!

The event-raising class keeps an implicit reference to the event handling
class via the Delegate. If you dereference the event source, then it will be
GC in time. If you dereference an event handler, the event source will keep
it around. Which is why its important for event handlers to use
RemoveHandler if they use AddHandler.

The Delegate is a type that contains a reference to the handler type & a
reference to the method in the handler type.

| I started doing this a I saw some code the other day where somone had
| attached to 5 different events, then had to detach from them all in
| order to clean up. Seemed tedious and error prone. I wondered why
| no-one had written a thing to do the detaching, then I found that it
| was a wee bit tricky. Hence this thread.
In the case of Forms handling control events detaching the events are not
necessary as the GC will see that one references the other & GC both when
there are no other references.

As I suggested above the only time you need to "worry" about it is when you
have a handler that can become dereference before the source. In which case
I normally add a method (commonly IDisposable.Dispose) to the handler type
to have it remove its handlers from the source.

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net
"sam.m.gardiner" <sa************@gmail.com> wrote in message
news:11**********************@j73g2000cwa.googlegr oups.com...
|I am the author of the source class and I am not using .Net 2.
|
| I am trying to create some code that will allow a event-raising class
| to remove all of the handlers that are attached to its events. This
| will prevent the handlers keeping references to the event-raising class
| and allow it to be garbage collected.
|
| I have obtained the reference to the event delegate (as david points
| out, this is a nested type) but I need the reference to MyEventEvent
| which is the _instance_ of this type that is contained in the class
| that contains the list of handlers. Once I have this list I can run
| through it and detach them all.
|
| I started doing this a I saw some code the other day where somone had
| attached to 5 different events, then had to detach from them all in
| order to clean up. Seemed tedious and error prone. I wondered why
| no-one had written a thing to do the detaching, then I found that it
| was a wee bit tricky. Hence this thread.
|
| Thanks for the article Randy, very informative. I'm not very up on my
| IL and I haven't tried to read it yet maybe I should learn... And
| david, I have tried something like this as I guessed it was private but
| I may have screwed it up. I'm trying to do this without having to know
| that the member ius called MyEventEvent, as this seems crappy.
| Although, this is very unlikely to change, so would probably work.
|
| If I get it running nicely I'll post it, as it should be only a few
| lines.
|
| sam
|
May 29 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.