2

I have event, for example like that:

public event EventHandler<NewReadyMessageEventArgs> NewReadyMessage

The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one). I.e. I need certain order of handlers execution.

I understand that in reality handlers will be executed one by one and so I just need to attach them in right order but that would be very error-phrone design.

I want to create separate handler and attach it. In this handler I just want to execute my two handlers in right order. What do you think and what would you suggest?

Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • 6
    Maybe you should only attach one handler and this one calls the second one by himself? – Uwe Keim Aug 20 '12 at 18:50
  • @UweKeim no first handler shouldn't know about second handler. – Oleg Vazhnev Aug 20 '12 at 18:50
  • 1
    Possible duplicate of: http://stackoverflow.com/questions/1645478/order-of-event-handler-execution – CodingGorilla Aug 20 '12 at 18:51
  • 1
    If you cannot have your handlers chain their calls, there's really nothing you can do. There's no way in .NET to control which handlers get executed when and in which sequence.... – marc_s Aug 20 '12 at 18:51
  • 2
    Sounds like a design flaw to me, if the order is important. You could try setting up some kind of event "queue" or something like that. – Uwe Keim Aug 20 '12 at 18:52
  • 1
    @UweKeim: order shouldn't be relevant, really - otherwise, it's a design smell in my opinion – marc_s Aug 20 '12 at 18:56

4 Answers4

7

The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one)

In this case, I would rethink your design. It likely makes more sense for the "first" handler to raise its own event.

The second handler could attach to that event, and have the results of both items.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • if it rains open an umbrella and go home. Do you suggest me to go home every time I open an umbrella? – Oleg Vazhnev Aug 20 '12 at 19:00
  • @javapowered If you want to guarantee that you won't go home until your umbrella is opened, I'd suggest you "go home any time the umbrella opens because of rain" - ie: Umbrella.Opened can say that it's opened due to rain. – Reed Copsey Aug 20 '12 at 19:04
  • I don't want to attach "go home" to "umbrella.opened". It seems it make sense to create just one handler which know what to do in which order... – Oleg Vazhnev Aug 20 '12 at 19:08
  • @javapowered In your case, though -I'd use one handler - on "You" - since you could "open the umbrella and go home" - there's no need for two subscribers. – Reed Copsey Aug 20 '12 at 19:09
  • also now imagine that I need to open umbrella, start smoking, call my friend and go home at exactly that order :) – Oleg Vazhnev Aug 20 '12 at 19:11
  • @javapowered You can do that - with one subscriber ("You") - *You* are doing a bunch of operations in response to one event, so there's no need for >1 subscriber. – Reed Copsey Aug 20 '12 at 19:12
  • I think so, I marking another answer as correct because it more correctly answers my question I guess. Your suggestion is also fine, just not for my case. But I do that in other parts of my program. – Oleg Vazhnev Aug 20 '12 at 19:14
2

I would not rely on the internal implementation to ensure that the handlers get called in a specific order.

If the handlers can't know about each other but you need them to run in a certain order I would create a "parent" handler that calls the other two handlers in the correct order.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
1

I would suggest implementing your own add implementation if you don't want the default multicast delegate with the default event add/remove implementation.

For more information see http://msdn.microsoft.com/en-us/library/cc713648.aspx

In case it wasn't obvious, if you don't use the default multicast delegate, invocation of subscribers needs to be implemented manually. The above link details how to write custom add/remove to use a multicast delegate. This answer assumes you don't use a multicast delegate For example, something like:

   private List<EventHandler> eventList = new List<EventHandler>();

   public event EventHandler Event1 
   {
      add { eventList.Add(value); }
      remove { eventList.Remove(value); }
   }

    private void RaiseEvent1()
    {
        foreach(var e in eventList)
        {
            e(this, EventArgs.Empty);
        }
    }

Use a SortedList if you want a specific order...

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
  • This does nothing to help, you're changing the add/remove not the execution. – CodingGorilla Aug 20 '12 at 18:57
  • @CodingGorilla Well, detailing not using "the default multicast" implies he wouldn't invoke the event subscriptions with a multicast delegate and do it with some custom algorithm (that he really didn't detail). So, yes, it does help. – Peter Ritchie Aug 20 '12 at 18:59
0

It sounds like this might be a place where you just need to have multiple (2) events.

If the order is important have two events, and have one that is simply fired right after the other. You can see this at, for example, the page lifecycle in ASP. There are lots of events, and in some cases they're all fired one after the other with thing really inbetween them other than a guarantee that all handlers of the previous event are run. That sounds just like your case here.

Servy
  • 202,030
  • 26
  • 332
  • 449