How can I control the order in which event handlers are fired?

Are event handlers executed in the order they are attached to the event? If not, can I apply some order to the event handlers so that they are called in a specific order?

+17
events
Nov 05 '08 at 2:28
source share
5 answers

Assuming a simple event implementation (using + = and - = in the delegate field, which in turn will use Delegate.Combine/Remove ), then yes, the event handlers will be called in the order in which they are signed. The warranty is indeed given in the Delegate.Combine documentation:

Return value

A new multicast (combinable) delegate with a call list that combines the call lists and b in this order.

See the event article for some examples of what Delegate.Combine/Remove does (and which events look like covers).

+17
Nov 05 '08 at 6:33
source share

Do NOT rely on event ordering. All event scheduling should be logically independent, as if they were happening in parallel.

Adding event handlers to other classes and streams may violate the intended ordering; this is simply not a safe assumption, and it contradicts the concept of events as independent, unbundled actions.

I will take it one step further and claim that if you have to accept an order for shooting events, you have a serious design flaw and / or abuse the events.

+5
Dec 17 '08 at 17:40
source share

You can have one event handler that calls other functions or delegates in that order.

+2
Nov 05 '08 at 2:31
source share

I would recommend wrapping it up.

Do something like that ...

 MyObject.MyEvent += new MyEventHandler(Wrapper); public void Wrapper() { Method1(); Method3(); Method2(); } 

That way, you are still hooking up the event, but you have full control over what is called.

+1
Nov 05 '08 at 3:46
source share

Sorry for the late reply.




I came across a situation where I have to deal with the order of event handlers.

I have a form, and when I click the button on the form, the object is added to the collection somewhere in my code.

The collection has an "Added" event, and two delegates are connected to it. One method deletes any item that has just been added to the collection, while the other displays a message to the user.




If I have some code examples, when the event fires, an "IndexOutOfRange" exception is thrown:

 // this methods hooks two delegates to MyCollection.Added event, but the order results in a "IndexOutOfRange" exception after the event is triggered HookEvents() { MyCollection.Added += new CollectionItemAddedHandler(DeleteItem_After_CollectionItemAdded); MyCollection.Added += new CollectionItemAddedHandler(ShowMessage_After_CollectionItemAdded); } // when user click a button on form, add a object to MyCollection Button_Clicked() { MyCollection.Add(new object()); } // at the moment a object is added into the collection, this method remove it DeleteItem_After_CollectionItemAdded(NewIndexArgs e) { MyCollection.Remove(e.NewIndex); // e.NewIndex represents the newly added item index in current collection } // at the moment a object is added into the collection, this method show its information (hey, but remember, I just remove it in the previous method) ShowMessage_After_CollectionItemAdded(NewIndexArgs e) { MessageBox.Show(MyCollection[e.NewIndex]); // tell user what is just added into the current collection // a "IndexOutOfRange" exception is thrown here.... } 



What this script will do correctly is that the ShowMessage_After_CollectionItemAdded method must be started first , and then it will be the DeleteItem_After_CollectionAdded method.

Although at first we can + = the ShowMessage ... method, sometimes we cannot predetermine this sequence until runtime .

0
Jul 08 '09 at 13:56
source share



All Articles