使用FileSystemWatchers安全地共享同一个事件处理程序吗?
让多个FileSystemWatchers使用相同的事件处理程序观察不同的目录是否安全?
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
或者我们必须将FileSystemWatcher包装在类如下的类中,以使事件处理程序是线程安全的吗?
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
这里使用帮助程序类:
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
答案 0 :(得分:3)
默认情况下,FileSystemWatcher
引发的事件在线程池线程上引发。这意味着事件处理程序中使用的任何数据都是“共享的” - 无论您是否有多个处理程序。您应该保护(例如lock
访问)此共享数据以避免损坏。
或者,您可以使用FileSystemWatcher.SynchronizingObject提供同步上下文,以便在FileSystemWatcher
上引发的所有事件都发生在单个或已知的线程上。如果事件处理程序触及GUI元素,通常会执行此操作。