Reputation: 20746
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
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
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 lock
s around the whole code, including the event handler invocation - so it will not run in parallel.
Upvotes: 1