views:

88

answers:

4

I have the following code where I am handling an event twice. However I always want to ensure that mynewclass always handles the event first and then the local event handler code fires. I understand the MyClass event should fire first as that is the one created first but because the thread and enqueuing is taking place, I think its taking too long and its doing something in myhandleeventlocal before I want it to do that. Any way I can wait for it to happen?

    public MyMainClass
    {

    private MyMethod()
    {
        MyClass mynewclass = new MyClass();
        mynewclass.myObject += MyHandler(myhandleventlocal);
        mynewclass.loadedevent += EventHandler(loadedevent)
    }

    private void myhandleventlocal()
    {

             //do stuff

    }

    private void loadedevent()
    {
         //do some stuff
     }

    }

    public MyClass
    {
         public MyObject myObject;
         public event loadedevent;
         public MyClass()
         {
               myObject = new MyObject();
               myObject += MyHandler(myhandlevent);

         }

         private void myhandlevent(long value, string detail)
         {

             //Start a thread
             //Enqueue value and detail
             //On seperate thread dequeue value and process it
             //Raise loadedevent event

         }

    }

UPDATE: I have updated my question and code to demonstrate the problem.

+2  A: 

By default the event handlers are called in the order you add them, so if you always add the handlers in the order you want them to fire then it should work.

From Jon Skeet's article on events and delegates:

[...] extra delegates are both added to and removed from the end of the list [...]

Note: You can override the default behaviour of events by changing the add and remove operations on your event to specify some other behaviour. You can then keep your event handlers in a list that you manage yourself and handle the firing order based on whatever rules you like.

Mark Byers
Although Jon's right, the spec doesn't specify firing order. Though I don't expect MS to change the game plan, if an app really depends on knowing the firing order, we take control of execution by implementing the `add` and `remove` elements of the event.
kbrimington
@kbirmington: +1 Good point, added.
Mark Byers
+1  A: 

If you can't guarantee the order the event handlers will be added, just add the one for mynewclass and then in that code call the other code.

ChrisF
A: 

Since event handlers are called in the order you add them, based on the code I see in your question, you can't make mynewclass's handler be called first. The event handler that MyClass creates is always added first.

One solution would be to control priority for the event handlers. Instead of using the builtin event handler +=/-= operators, you would instead have methods for adding and removing events where you could specify ordering explicitly. That way, if a class knows it needs to handle the event first, it could ask for such. Be careful, though, because you could easily run into a situation where multiple classes are each insisting that they handle the event first.

Here is some quick and dirty code to get you started:

class MyClass {
    private LinkedList<MyEventHandler> eventHandlers;
    public enum Ordering { First, Last, ... };
    public void AddHandler(MyEventHandler handler, Ordering order) {
        switch(order) {
            case Ordering.First:
                eventHandlers.AddFirst(handler);
                break;
            // fill in other cases here...
        }
    }
    public void RaiseEvent() {
        // call handlers in order
        foreach(MyEventHandler handler in eventHandlers)
            eventHandler();
    }
}
siride
A: 

Referring to siride solution, you can also implement your handlers and decide the position that way. Like inverting the order (always add at the begin) or add some logic.

Sid
oops! mark byers already said that...;)
Sid