Re: Maintain list of attached event handlers (.Net 1.1)
- From: "Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Tue, 10 Jul 2007 17:53:10 -0700
On Tue, 10 Jul 2007 16:57:14 -0700, Armin Zingler <az.nospam@xxxxxxxxxx> wrote:
Why /not/ detach them right away? :-) I know, because then I would not have
the problem,
No. That's not true. The question of being able to unsubscribe event handlers later has nothing to do with whether you also unsubscribe as they are raised. I personally think unsubscribing is a waste of time, but it doesn't affect the more general issue. So, you should stop worrying about it. If you want to unsubscribe, fine. It's not causing a problem.
but in general it is not a fault to detach them immediatelly.
Though, the question remains how I can store the information that "I
attached this handler to that event".
Why do you need this information? You obviously can enumerate all of the objects for which you want to subscribe to an event or events. So, do the same enumeration when you want to unsubscribe, and unsubscribe from every event of every object that you subscribed to in the first place.
For some objects, this operation will do nothing, because you've already unsubscribed. But that's not a problem.
Background:
The tree mentioned describes an execution plan in another thread. Each node
in the tree represents a piece of work. A node contains status information
and fires "Started" and "Done" events. Whenever I receive the "Started" or
"Finished" event, I unsubcribed from it because it will never fire again.
Right, I am not forced to unsubscribe immediatelly, but IMO it's more
correct than wrong.
I disagree, but you are writing the code, so obviously your opinion carries more weight. Regardless, as I mentioned this question has nothing to do with how you resolve the unsubscription at the end.
In the end, when closing the Form, I want to unsubsribe
to all remaining handlers that are still attached.
So do that. Traverse your tree and unsubscribe from all the events, just as you traversed the tree and subscribed to start with.
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. This is a fundamental limitation, granted. But it doesn't prevent things from being done. It just changes how they need to be done.
In C, you might do something like this (if C allowed this syntax, that is):
public event MyHandlerType myevent;
and then later do this:
MyHandlerType *pevent = &myevent;
*pevent += MyEventHandler;
so that even later you could do this:
*pevent -= MyEventHandler;
That's not possible in C#. However, that doesn't mean that you can't instead retain a reference to the object with the event itself, and gain access to the event later that way.
So instead, you'd write something like this:
class MyEventRaisingClass
{
public event MyHandlerType myevent;
...
}
and then later do this:
MyEventRaisingClass raiser = ...;
raiser.myevent += MyEventHandler;
and then even later do this:
raiser.myevent -= MyEventHandler;
The two are basically equivalent. The only difference is that in one case you know only the event instance, while in the other case you have the reference to the entire containing class instance.
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. As I mentioned, it is basically equivalent.
There are, however, some things that don't make sense to me in your code..
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. 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.
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.
Pete
.
- Follow-Ups:
- 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
- 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
- Maintain list of attached event handlers (.Net 1.1)
- Prev by Date: Re: Application Design Question
- 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
|