Is using FileSystemWatchers sharing the same event handler safe?
Is it safe having multiple FileSystemWatchers watching different directories using the same event handler?
Class Snippets
Private _watchPaths As New List(Of String) From {"x:\Dir1", "x:\Dir2"}
Private _watchers As List(Of FileSystemWatcher)
Private _newFiles As New BlockingCollection(Of String)
Sub Watch()
Dim _watchPaths As New List(Of String) From {"x:\Dir1", "x:\Dir2"}
Dim watchers As List(Of FileSystemWatcher)
For Each path In _watchPaths
Dim watcher As New FileSystemWatcher
AddHandler watcher.Created, Sub(s, e)
_trace.DebugFormat("New file {0}", e.FullPath)
'Do a little more stuff
_newFiles.Add(e.FullPath)
End Sub
Next
End Sub
End Class
Or must we wrap the FileSystemWatcher in a Class like the following to make the event handlers thread-safe?
Class FileWatcher
Private _fileSystemWatcher As New FileSystemWatcher
Public Sub Start(path As String, filter As String, action As Action(Of Object, FileSystemEventArgs))
With _fileSystemWatcher
.Path = path
.Filter = filter
.EnableRaisingEvents = True
AddHandler .Created, Sub(s, e)
action(s, e)
End Sub
End With
End Sub
Public Sub [Stop]()
_fileSystemWatcher.Dispose()
End Sub
End Class
Here the usage of the helper Class:
Sub Watch
For Each path In _watchPaths
Dim Watcher as new FileWatcher
watcher.Start(path, "*.txt"), Sub(s, e)
_trace.DebugFormat("New file {0}", e.FullPath)
'Do a little more stuff
_newFiles.Add(e.FullPath)
End Sub)
Next
End Sub
Events raised by the FileSystemWatcher
are, by default, raised on thread pool threads. Which means any data used within the event handler is "shared"--regardless of whether you have multiple handlers. You should guard (e.g. lock
access) this shared data to avoid corruption.
Alternatively, you can use FileSystemWatcher.SynchronizingObject to provide a synchronization context so that all events raised on a FileSystemWatcher
occur on a single, or a known thread. This is typically done if your event handlers touch GUI elements.