How to prevent subscribers to an event from conflicting with each other? - c#

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: 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?

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.

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.

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.

Related

.NET Event Handling When an Event Is Fired While Another Event Handler is Already Running

There is an issue that makes me curious about for quite some time.
Assume this scenario:
You created a program in C#, which has some classes inwhich you defined some events,
and other classes consume those events - they implement event handler methods for them.
My question:
What are the CLR's "rules" for running the event handler(s), for cases where events happen simultaneously?
If one event handler is running, and another event was raised now, will the CLR let the current event handler finish, and then just go to the next event handler? (the "second" event might be a second raise of the same event, or a different event)
Or is there a case where the CLR pauses the current event handler due to an event that came in the middle, then runs the second event handler, and then resumes back to the middle of the first event handler that was left?
Any info or article that makes an order in this, will be greatly appreciated.
BTW:
For this question, please assume 2 possible situations:
1) The classes with the events and event handlers are not Controls
(simple classes that you write, that inherit type object and not type Control)
2) The classes with the events and event handlers are inheriting class Control (Windows Forms)
I mention this because maybe the behavior/rules are different between the two.
Also, I would be grateful if you can relate to following things, that might affect the answers to these 2 questions:
- Application.DoEvents() method
- Timers
- any other class/method like this that might give different results beyond the simple ones that we might think of in the "normal" case..
Thank you
This has nothing to do with the CLR or the language. It's purely based on the specific implementation of the class defining the method. It can be written such that it fires of the event while handlers for a previous invocation are still running, or it could not. If you're dealing with a winforms program then most object firing events are firing them in the UI thread, so since there is only one thread that can be firing the events it can't ever fire them while other handlers are still running, but there are other objects that aren't forcing their usage to a single thread and as such can fire an event while handlers for a previous invocation are still running.
So all you can really do is look at the documentation/source code or do some experimental tests to see what any particular class does, or be safe and assume the worst case. There is no general case answer.

Windows UI Automation: thread blocking when adding event handlers

I am writing a C# program, which uses the UI Automation via Com interop. However, I am having a problem adding/removing an event handler from within another event handler:
My program starts up a new MTA thread, and on that thread, calls AddFocusChangedEventHandler().
I want to monitor for property changes on the focused element. So within the focus-changed handler, I call RemovePropertyChangedEventHandler() on the previously focused element, and AddPropertyChangedEventHandler() on the newly focused element.
However, I find that after about two focus changes, I stop getting either focus-changed, or property-changed, events. My hunch is that something is blocking the background thread.
If I remove the property-changed code, then just the focus tracking works just as expected.
I'm not sure if this is pertenant - but the documentation states that event handlers should be added/removed on the same thread. Since I'm calling AddPropertyChangedEventHandler() in one focus-changed event, and RemovePropertyChangedEventHandler() in another focus-changed event, it's possible that the two calls are being executed on different threads. However, I doubt this to be the case - and even if it were, it shouldn't exhibit the blocking behavior I see. Just mentioning it here for completeness.
There may be multiple problems here. But it's worth noting that after you RemovePropertyChangedEventHandler, you may still get some more events if there are multiple events on the same item (you'll for example get multiple child_added structure changed events if there are multiple children added to an item, it may be similar with multiple properties changing - but not sure). So, if you get multiple events, your code will be called multiple times, probably messing things up.
Another issue is, as you've pointed, you shouldn't subscribe / unsubscribe to events from different threads. But I think this is relevant when there's a chance that these actions are not synchronized - if you're subscribing and unsubscribing to different events (likely in your case) then things will get messy - I'll hazard to say that if you do the subs/unsubs in sequence by some lock mechanism then it should be fine.

Do .NET buttons fire events only if there's at least one subscriber?

I'm designing a client-side test script generation application. The application finds every automation element in the provider and registers a listener on to each automation element in the provider. Whenever the user interacts with the provider's UI, the automation elements fire events which are recorded in my application.
Right now, the buttons on the main form fire events, but the buttons in subforms don't fire events. I realized that subform buttons don't have subscribers in the provider's code. So my question is, do .NET buttons only fire events if there's at least one subscriber?
This is a bit like asking "If a tree falls in a forest and there's no one to hear it, does it make a sound?" If you go there to find out, there is someone to hear it.
When a handler is attached to a .NET event, a collection object is created and a delegate added to it. When an event occurs, the framework checks for the existence of this collection. When present, its elements are enumerated and invoked, otherwise event dispatch terminates early.
"[D]o .NET buttons only fire events if there's at least one subscriber?"
If by "fire events" you mean "invoke delegates to call event handlers" then clearly this can only occur when there are delegates. Obviously if there aren't any then they can't be invoked. In the sense of "Does the framework look for delegates to call when there aren't any" then the event does fire in the absence of handlers.

C# Event Handling Order

The scenario is an event on a buffer, that informs interested classes when there is data available to be collected. The event is fired as soon as new data is written to the buffer. When this is fired, the delegate for the event (in the interested class) starts reading data from the buffer.
My question is, if the event were fired again (before the method had finished reading all the data from the buffer) would the reading method be 'reset' or would the event wait for the method to finish reading the data before calling it again?
The event could only be fired again before the method had finished reading if it were fired on another thread. The event handlers will then (by default) be called again in that separate thread. There's no concept of an existing method being "reset", nor would it wait for the already-running handlers to finish before firing again.
Of course, you could potentially change how the handlers work, or how the event is fired - perhaps ensuring that the event handlers are only called from a single thread, with some sort of queue of events. It's impossible for us to tell whether that's appropriate for your situation though.
Neither, it would execute it alongside (in parallel), if on separate threads - otherwise execution would be blocking anyway.
Unless you've put Application.DoEvents() in your code (which is a horrible thing to do) then your event won't be interrupted.
In a multithreading scenario, there's the possibility of them running in parallel. I don't use multiple threads and events both at the same time, so I can't really say much about that, but it seems like Jon's covered that one nicely with his answer.

Design question in WPF .NET

Event Management
An event is an entity which can be triggered when specified condition is met. User creates an event giving following inputs:
Event Name
Event Type ( event can be categorized )
Based on event type there is a condition which user has to specify. This condition is a criterion for raising the event.
Event has Notification methods like: SMS, Email , Playing sound etc. And user is
notified by whichever notification user has specified.
User may specify all notification methods, it means user is notified through SMS, email and playing sound when event is raised condition is met.
Think of a wizard to enter all the above. Please suggest me a flexible design to implement this.
Udi Dahan has written two excellent articles (on his blog and for MSDN) on the Domain Event Pattern which sounds like it will fit your purpose.
The Domain Event Pattern does have its downsides; with the most common complaint being that it's difficult to find out what events have been subscribe to and it can become unmanageable. That being said I've used it before and would highly recommend it.

Categories