views:

87

answers:

3

Say I have an event with 2 subscribers (everything occurs in the same thread) - one subscriber writes to a log file, the other shows a MessageBox.

If the MessageBox is the first on the subscription list, then the log entry is not written until the after the user closes the message box. So the time in the log entry will really be the time the message box was closed, not the time the event occurred.

It seems the best solution is to have the log writer subscribe to the event before the code that displays the message box. However, in a similiar question here: http://stackoverflow.com/questions/374398/are-event-subscribers-called-in-order-of-subscription

the best answer was to never rely on the order of the subscribers. So how do I prevent the conflict without worrying about their order?

A: 

EDITED:

Are you in control of the event code? If so, you can make sure it's never implemented in a pathologically weird way which reorders things. You can even document that as part of the event itself: "Handlers to this event are always called in subscription order, synchronously."

To be honest, I'd really expect any event which didn't go along with that to explicitly document it.

Jon Skeet
sorry - I was referring to S. Lowe's answer
R.B.
@R.B. - Okay, but the same logic applies. Are you in control of the event code, so can guarantee that it won't mess things around?
Jon Skeet
I have control of the event code, but not the subscribers.
R.B.
That means you *can* guarantee that the handlers will be called in order, in the same thread - but it sounds like you couldn't make sure that the logged would be called before the message box anyway...
Jon Skeet
+1  A: 

All of the individual event subscribers need to play well with others. The proper thing is for the event that shows the MessageBox to launch a background thread and show the MessageBox from there.

JSBangs
Will that work - I thought all UI had to come from the main thread.
ChrisF
You can create a popup from another thread, editing the main form is more challenging though.
Paul Creasey
A messagebox created in the background won't stay on top.
R.B.
You can work around the UI thread requirement. One idea is to enqueue and event consumed by the main thread that causes the message box to appear.
JSBangs
+1  A: 

According to the documentation on events in the MSDN C# programming guide, events have the following properties (key point is bold):

  • 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.
  • Events are typically used to signal user actions such as button clicks or menu selections in graphical user interfaces.
  • When an event has multiple subscribers, the event handlers are invoked synchronously when an event is raised. To invoke events asynchronously, see Calling Synchronous Methods Asynchronously.
  • Events can be used to synchronize threads.
  • In the .NET Framework class library, events are based on the EventHandler delegate and the EventArgs base class.

Looks like the best bet is to use BeginInvoke on the events.

mkedobbs