Home > database >  Newbie question on event handling management, what if you add or subtract too much delegates?
Newbie question on event handling management, what if you add or subtract too much delegates?

Time:10-25

In my program, sometimes a function needs to be executed when an event is fired, sometimes not, and there seems to be a problem with this. In order to understand that problem, I would like to know what happens in the following cases:

_manager.InputOkHandler  = InputHandler; // add the InputHandler to the event.
...
_manager.InputOkHandler  = InputHandler; // add the same InputHandler to the event again. (1)
...
_manager.InputOkHandler -= InputHandler; // remove an/the InputHandler from the event. (2)

... and at another moment:

_manager.InputOkHandler  = InputHandler; // add the Input Handler to the event.
...
_manager.InputOkHandler -= InputHandler; // remove the InputHandler from the event.
...
_manager.InputOkHandler -= InputHandler; // remove an InputHandler from the event. (3)
  • (1) : will the InputHandler be added twice? If yes, what does this mean?
  • (2) : will only one InputHandler be removed or both (if possible)?
  • (3) : will this raise an Exception? If yes, which one?

... and finally: is it possible to show a list of all "subscribed" functions/methods to an event and how?

CodePudding user response:

Ok, so I've got a snippet to answer all of those:

public class A
{
    public event EventHandler MyEvent;

    public void RaiseEvent()
    {
        MyEvent?.Invoke(null, EventArgs.Empty);
    }

    public Delegate[] GetInvocationList()
    {
        return MyEvent.GetInvocationList();
    }
}

public void del1(object sender, EventArgs args)
{
    Console.WriteLine("1");
}

public void del2(object sender, EventArgs args)
{
    Console.WriteLine("2");
}

var a = new A();

a.MyEvent  = del1;
a.MyEvent  = del1;
a.MyEvent  = del2;

a.RaiseEvent();
/*
Outputs: 
1
1
2
*/

a.MyEvent -= del1;

a.RaiseEvent();
/*
Outputs:
1
2
*/

a.MyEvent -= del2;
a.MyEvent -= del2;

a.RaiseEvent();
/*
Outputs:
1
*/

Console.WriteLine($"{a.GetInvocationList().Length} subscriptions left")
/*
Outputs: 
1 subscriptions left
*/

So to answer all your points in order:

  1. Yes, the handler will be added twice, which means it will be called twice when the event is raised
  2. Only one handler will be removed
  3. No, no exceptions will be thrown if you try to remove a handler which is not present in the subscriptions
  4. You can access the collection of subscriptions, but as an array of delegates and only in the class where the event was declared.

CodePudding user response:

will the InputHandler be added twice? If yes, what does this mean?

Yes, and it means that the handler will be invoked twice whenever the event is raised.

will only one InputHandler be removed or both (if possible)?

Only one

will this raise an Exception? If yes, which one?

No.

You should be careful to only add event handlers once, and deterministically remove it. A typical case would be to add the event handler in the constructor, and remove it in the dispose method. In some cases it might make sense to use a helper method for registration that returns a IDiposable, so you can write using(MyEvent.Register(MyEventHandler)){....}.

  • Related