Re: Maintain list of attached event handlers (.Net 1.1)



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
.



Relevant Pages

  • [PATCH 1/3] remove bogus softirq_pending() usage in cris
    ... /* this function links in a handler into the chain of handlers for the ... To unsubscribe from this list: send the line "unsubscribe linux-kernel" in ...
    (Linux-Kernel)
  • Re: Event Subscription. Why?
    ... Each time you add or remove a subscriber you will create a new ... each call to MyEvent will only work with the current list. ... and actually it never will unless you unsubscribe (causing a nice memory ... managed object, and as long as the publishing class has a reference to it, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Maintain list of attached event handlers (.Net 1.1)
    ... Your requirement to unsubscribe when the event fires is completely independent of how you unsubscribe other events later. ... A basic rule of event management is that when you subscribe the first handler, the reference to the event has to be instantiated. ... While you didn't actually post any code that showed such an enumeration, I will take as granted that somewhere you actually do. ... It's simple, it works, and is MORE performant than trying to maintain a list or lists or other data structures as various events are raised and unsubscribed from. ...
    (microsoft.public.dotnet.framework)
  • RE: Copyright Issues
    ... The company that supplies these vending machines is called Naughty Vend ... reference to and copyright credits to the original artist. ... the BSD Daemon is copyrighted by Marshall Kirk ... To unsubscribe, ...
    (freebsd-questions)
  • Re: Delegates and Events confusion
    ... I figured that I needed to unsubscribe in some way but since I ... wasn't storing an internal reference to the subscriber. ... In ClassC I hook into the ClassA ...
    (microsoft.public.dotnet.languages.csharp)