Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the subscribers of an event?

Tags:

c#

events

I need to copy the subscribers of one event to another event. Can I get the subscribers of an event (like MyEvent[0] returning a delegate)?

If this is not possible I would use the add accessor to add the delegates to a list. Would that be the best solution?

like image 233
weiqure Avatar asked Feb 21 '09 08:02

weiqure


People also ask

Can an event have multiple subscribers?

The publisher determines when an event is raised; the subscribers determine what action is taken in response to the event. An event can have multiple subscribers. A subscriber can handle multiple events from multiple publishers. Events that have no subscribers are never raised.

Which of the statements can be used to subscribe to an event?

To subscribe to events programmatically Use the addition assignment operator ( += ) to attach an event handler to the event.

What is event subscription Navision?

An event subscriber is a C/AL function that subscribes to, or listens for, a specific event that is declared by an event publisher function. The event subscriber includes code that defines the business logic to handle the event. When the published event is raised, the event subscriber is called and its code is run.

What is the function of event subscriptions?

An event subscription is a registration indicating that a particular event is significant to a particular system and specifying the processing to perform when the triggering event occurs. You can define your event subscriptions in the Event Manager.


4 Answers

C# events/delegates are multicast, so the delegate is itself a list. From within the class, to get individual callers, you can use:

if (field != null)  {      // or the event-name for field-like events     // or your own event-type in place of EventHandler     foreach(EventHandler subscriber in field.GetInvocationList())     {         // etc     } } 

However, to assign all at once, just use += or direct assignment:

SomeType other = ... other.SomeEvent += localEvent; 
like image 154
Marc Gravell Avatar answered Sep 22 '22 15:09

Marc Gravell


If the event is one published by another class, you can't - at least, not reliably. While we often think of an event as being just a delegate variable, it's actually just a pair of methods: add and remove (or subscribe and unsubscribe).

If it's your own code that's publishing the event, it's easy - you can make the add/remove accessors do whatever you like.

Have a look at my article on events and see if that helps you. If not, please give more details about what you want to do, specifying which bits of code you're able to modify and which you aren't.

like image 42
Jon Skeet Avatar answered Sep 19 '22 15:09

Jon Skeet


In case you need to examine subscribers of an external class' event:

EventHandler e = typeof(ExternalClass)
    .GetField(nameof(ExternalClass.Event), BindingFlags.Instance | BindingFlags.NonPublic)
    .GetValue(instanceOfExternalClass) as EventHandler;
if (e != null)
{
    Delegate[] subscribers = e.GetInvocationList();
}
like image 21
Monsignor Avatar answered Sep 20 '22 15:09

Monsignor


Update (thanks to commenters): delegate immutability means that cloning achieves nothing over an assignment.

When one writes:

myDelegate += AHandler

A completely new delegate instance is created and assigned to myDelegate.

Therefore, the code below would work exactly the same without the Clone call.


MulticastDelegate (the underlying type) has a Clone method.

To be able to get to the underlying delegate you might need to avoid the usual helper that the event keyword generates, and manage things directly (custom add and remove accessors).

To show this:

public class Program {
    public delegate void MyDelegate(string name);

    public event MyDelegate EventOne;

    public void HandlerOne(string name) => Console.WriteLine($"This is handler one: {name}");
    public void HandlerTwo(string name) => Console.WriteLine($"This is handler two: {name}");
    public void HandlerThree(string name) => Console.WriteLine($"This is handler three: {name}");

    public void Run() {
        EventOne += HandlerOne;
        EventOne += HandlerTwo;
        Console.WriteLine("Before clone");
        EventOne("EventOne");

        MyDelegate eventTwo = (MyDelegate)EventOne.Clone();
        MyDelegate eventTwo = EventOne;
        Console.WriteLine("After clone copy");
        EventOne("EventOne");
        eventTwo("eventTwo");

        Console.WriteLine("Change event one to show it is different");
        EventOne += HandlerThree;
        EventOne("EventOne");
        eventTwo("eventTwo");
    }
    private static void Main(string[] args) => (new Program()).Run();
}
like image 40
Richard Avatar answered Sep 22 '22 15:09

Richard