FrozenHeart
FrozenHeart

Reputation: 20746

Event handlers and multithreading in .NET framework

Can event handlers like FileSystemEventHandler related to FileSystemWatcher class be called from the different threads at the same time (parallel to each other)? Is there any guarantees about it at all?

Upvotes: 0

Views: 145

Answers (2)

György Kőszeg
György Kőszeg

Reputation: 18013

The add and remove handlers of the FileSystemWatcher class are nothing special so - as in most cases - it is completely indifferent, from which thread you subscribe a method. If you set the FileSystemWatcher.SynchronizingObject, the delegate will be invoked on that object by a BeginInvoke call; otherwise, it will be invoked in the tread where your FileSystemWatcher resides.

The methods of a delegate will be called after each other in the thread of the invoker, so there is no syncing issue among them. However, if in your other threads you use common resources with the subscribed methods, you must take care of syncing as usual.

Upvotes: 0

Luaan
Luaan

Reputation: 63722

In general, there are no guarantees.

The event handler runs on the same thread it is invoked on, but that doesn't really tell you anything - for all you know, it could be invoked with something like ThreadPool.QueueUserWorkItem(() => EventHandler()). System.Timers.Timer is one example - the timer callbacks are invoked on a thread pool thread, and multiple can run in parallel.

The major exception are events used in terms of some synchronization context - for example, GUI events (including System.Windows.Forms.Timer) in Windows Forms will only ever launch on the GUI thread. However, the documentation should explicitly specify that the event handlers have some particular thread affinity - it certainly isn't the default assumption.

FileSystemWatcher in particular is even trickier. If it has a SynchronizingObject set, it will have thread affinity - the handlers will be invoked on the synchronizing object. If that synchronizing object is a Form, for example, the handler will always run on the GUI thread and it will never run in parallel. Other synchronizing objects may behave differently (you could always make your own synchronizing object that posts the delegate to the thread pool, for example). Note that the invocation is asynchronous - it does BeginInvoke, not Invoke - so it can very much result in parallel execution if your synchronizing object does something like ThreadPool.QueueUserWorkItem.

If there is no synchronizing object, the handler runs on the same thread that received the notification. Since FileSystemWatcher runs on a IOCP, it's pretty safe to assume that it's just borrowing a threadpool thread for the duration of the callback. However, it also explicitly locks around the whole code, including the event handler invocation - so it will not run in parallel.

Upvotes: 1

Related Questions