Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are event subscribers called in order of subscription?

Is it safe to assume that event subscribers are called in order of subscription?
Example:

void One(object sender, EventArgs e) {}
void Two(object sender, EventArgs e) {}

event EventHandler foo;

foo += One;
foo += Two;

Is One() always called before Two() when the event is fired?

Edit:
You should ofcourse not rely on it, I was just thinking. The idea was, that multicast delegates are similary to the COMMAND pattern. So I was just wondering. Ususally you would use a collection that keeps the order for COMMANDs so you can do undo/redo/whatever.

like image 651
EricSchaefer Avatar asked Dec 17 '08 12:12

EricSchaefer


People also ask

Can an event have multiple subscribers?

An event can have multiple subscribers. A subscriber can handle multiple events from multiple publishers. Events that have no subscribers are never raised.

What does subscribe to an event mean?

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.

What is event subscriber in 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.


4 Answers

Given that implementation, yes, they will always be called in that order.

If the event actually uses some weird and wonderful way of handling subscriptions, it could do different things - but "normal" implementations will do the right thing.

To be clear, subscribing to an event handler just means invoking the appropriate "add" part of an event. If the event handles this by doing something like:

myHandler += value; 

that gets translated into

myHandler = Delegate.Combine(myHandler, value); 

and Delegate.Combine guarantees the ordering. However, if you had an event like this:

private LinkedList<EventHandler> eventHandlers = new LinkedList<EventHandler>;  public event EventHandler Foo {     add     {         eventHandlers.AddFirst(value);     }     remove     {         // do stuff here too     } } 

and then fired the event by doing something like:

foreach (EventHandler handler in eventHandlers) {     handler(this, EventArgs.Empty); } 

then the handlers would be called in the reverse order.

Summary: For all sane events, you can rely on the ordering. In theory, events can do what they like, but I've never seen an event which doesn't maintain the appropriate ordering.

like image 162
Jon Skeet Avatar answered Sep 19 '22 13:09

Jon Skeet


Pay very close attention to the caveats given by Jon Skeet - "Given that implementation...". In other words, make the slightest change (multiple threads, other handlers, etc.) and you risk losing the order-of-execution invariance.

Do NOT rely on event ordering. All event dispatches should be logically independent, as if they were occurring in parallel. Events are logically independent actions.

I'll go one step further, and assert that if you have to assume an order for events firing, you have a serious design flaw and/or are misusing events.

like image 26
Steven A. Lowe Avatar answered Sep 19 '22 13:09

Steven A. Lowe


Even if they are called in the correct order I would try to not write code that relies on a previous delegate having been fired for it to function correctly.

If Two() is dependant on something that One() is doing then either attach a single delegate that calls the two methods in the correct order, or have Two() invoke One() when necessary.

like image 20
Paul Avatar answered Sep 19 '22 13:09

Paul


The quick answer would be "It's none of your business" :)

An event is asynchronous by nature. This means that you are not waiting for an event to be fired or expecting it to occur at a given time. They just happen and then you take action. Wanting to know 'when' or trying to figure out 'how' is going to break this nature.

Maybe in this case you don't need an event-based approach to get things done?

What Jon Skeet said is technically correct for the current implementation, but maybe it won't in c#8.5 or VBasic 15.0. Relying on implementation details is always going to do more harm than good.

like image 21
Trap Avatar answered Sep 21 '22 13:09

Trap