Re: Maintain list of attached event handlers (.Net 1.1)
- From: "Armin Zingler" <az.nospam@xxxxxxxxxx>
- Date: Wed, 11 Jul 2007 05:43:20 +0200
"Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx> schrieb
For some objects, this operation will do nothing, because you've
already unsubscribed. But that's not a problem.
To make it a bit shorter, I'll try to resume:
You twice say that it is not a problem (to immediatelly unsubscribe). So, we
can say that it is up to me. But if I have the choice between either listen
to an event that will never occur, or don't listen to it anymore, the latter
obviously makes more sense. That's the reason why I unsubscribe
immediatelly.
> Though, it is still interesting for me that I can not store the
> information
> in a list. Actually each item would be a pair of two objects: One
> pointing
> to the event (type: Multicastdelegate), the other one pointing to
> the event
> handler (Delegate).
In C#, there are no references to references.
Why "references to references"? (I'm using VB.Net BTW) A reference to a
MulticastDelegate object is possible. The event is a MulticastDelegate
object. My only problem is that it is private in the class.
[Meanwhie I know what you might be referring to but I'm not sure yet; see my
example and the explanation at the end]
[C]
Sorry, I can not comment the C-Code.
[C#]
[...]
> Below[1] I inserted the real-world code that I had to write due to
> a lack of solution that I am looking for. You don't have to read
> it because it's lengthier.
As near as I can tell, you are doing what I described above, in that
you retain a reference to the object containing the event rather
than to the event itself. Frankly, I don't know why you think that
this is worse than having a reference to the event.
Because it's more work. If I have to reference the object, I will have to
handle different
object types and different events individually. I just want a simple loop:
for each item in mylist
removehandler ...
-or-
[delegate].Remove ...
next
Sort of p-Code, but that's all I am looking for.
There are, however, some things that don't make sense to me in your
code.
Sorry, but everything makes sense and works well.
It doesn't actually explain the issue you're asking about, because
you don't appear to have included all of the code that does stuff. In
particular, I don't see any of the setup, nor is clear how events
are actually raised.
Yes, I did not include the whole code. The code explains well how I have to
handle the different events individually because the code is not based on a
base class (like MultiCastDelegate) that is common to all events, no matter
which object and no matter which event.
But beyond that, you appear to be removing the
same handler twice. Once in the event handling method itself:
RemoveHandler Status.Started, AddressOf OnCodeBlockStarted
And then again in the Remove() method of a class the purpose for
which I have yet to determine:
Public Sub Remove()
RemoveHandler obj.Started, handler
End Sub
In addition, every time an event handler is called, you enumerate a
list of all known subscribed event handlers (I think...again, you
left out details that would clarify this). In what way is that
better than simply enumerating all of the objects when the form is
finally unloaded and unsubscribing from each object there? It
certainly results in a lot more execution of code (it's essentially
an O(N^2) algorithm, as opposed to the O(N) algorithm that both John
and I have proposed to you.
I don't remove anything twice. After removing the handler, I remove the item
from the list. If it's not in the list anymore, it won't be removed again
when the Form is destroyed.
You are right, the loop to find the item in the list was a quicky. Could be
a hashtable or whatever. But it doesn't matter. If you want to remove
something from a list, it has to be done.
> It shows that I currently have to handle each event individually.
> It was a lot to type even though there were only two events.
Not that I think that the method that it appears you are using is
all that great anyway, but I don't see how typing 13 lines for a
class specific to the event is really all that big of a deal.
Compared to
class Item
event as multitaskdelegate
eventhandler as delegate
end class
it is pretty much to type, and in real-world there are some more events, as
a consequence some more "Class HookedXYZEvent", and some more arraylist and
some more loops to process the arraylists. If I could keep it all in one
list (of course, without different types of list items), it would be simple
in one go.
[Later....]
An example how it (almost) works. Comments see below.
Public Class Form1
Class C1
Public Event Progress(ByVal p As Integer)
Public ReadOnly Property MCD() As MulticastDelegate
Get
Return ProgressEvent
End Get
End Property
Public Sub Raise()
RaiseEvent Progress(0)
End Sub
End Class
Class C2
Public Event Done()
Public ReadOnly Property MCD() As MulticastDelegate
Get
Return DoneEvent
End Get
End Property
Public Sub Raise()
RaiseEvent Done()
End Sub
End Class
Private Class Item
Public [event] As MulticastDelegate
Public Handler As [Delegate]
Public Sub New(ByVal [event] As MulticastDelegate, _
ByVal Handler As [Delegate])
Me.event = [event]
Me.Handler = Handler
End Sub
End Class
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim al As New List(Of Item)
Dim o1 As New C1
Dim o2 As New C2
Dim d1 As New C1.ProgressEventHandler(AddressOf OnProgress)
Dim d2 As New C2.DoneEventHandler(AddressOf OnDone)
'add the event handlers...
AddHandler o1.Progress, d1
AddHandler o2.Done, d2
'...and remember which events I handle.
al.Add(New Item(o1.MCD, d1))
al.Add(New Item(o2.MCD, d2))
o1.Raise()
o2.Raise()
'...
'later: Remove all event handlers
For Each i As Item In al
[Delegate].Remove(i.event, i.Handler)
Next
o1.Raise()
o2.Raise()
End Sub
Private Sub OnProgress(ByVal p As Integer)
MsgBox("OnProgress")
End Sub
Private Sub OnDone()
MsgBox("OnDone")
End Sub
End Class
Comments:
- You see that the MCD properties make the internal MCDs public.
- This enables me storing a reference on them externally.
- This is usually not done, but only in this example. At least it is not
possible with classes authored by somebody else.
- The main point: In the loop that removes the handles, I don't have to care
about the object types and the events. All in one go! In addition: I don't
have to write one Item class for each event I want to handle.
Though, why I wrote it "almost" works: What I did not know until know is
that the invocation list of a MultiCastDelegate object (MCD) seems to be
readonly. I can only remove one item from the invocation list by creating a
new MCD. As a consequence, I would have to store the new MCD back in the
object - which is obviously not an option and not possible at all for
foreign classes.
Bottom line, the example shows how to store the information that I want to
store: I want to remember that I added /this/ handler to /that/ event
without individual handling different objects and events because the
event concept is the same for all of them. I also think that the example
makes clear what was my intention, and that it is - almost - possible. :-)
Please don't get me wrong: I use .Net since the first public SDK preview (in
Y2K?), and I am a programmer for 20 years now, so I (usually ;-) ) know what
I do. I don't insist on anything, but I thought that events have a common
concept, common base clases, and therefore it's not absurd to
think..uhhm..what I think. Now it turned out that under the hood called
"Events" there is something going on that makes it impossible to work as
intended.
Anyways, thanks a lot for your time and trying to help!
Armin
.
- Follow-Ups:
- Re: Maintain list of attached event handlers (.Net 1.1)
- From: Peter Duniho
- Re: Maintain list of attached event handlers (.Net 1.1)
- References:
- Maintain list of attached event handlers (.Net 1.1)
- From: Armin Zingler
- Re: Maintain list of attached event handlers (.Net 1.1)
- From: John Saunders [MVP]
- Re: Maintain list of attached event handlers (.Net 1.1)
- From: Armin Zingler
- Re: Maintain list of attached event handlers (.Net 1.1)
- From: Peter Duniho
- Maintain list of attached event handlers (.Net 1.1)
- Prev by Date: Re: Maintain list of attached event handlers (.Net 1.1)
- Next by Date: Re: Thread safety of events
- Previous by thread: Re: Maintain list of attached event handlers (.Net 1.1)
- Next by thread: Re: Maintain list of attached event handlers (.Net 1.1)
- Index(es):
Relevant Pages
|