使用共享相同事件处理程序的 FileSystemWatchers 安全吗?

Pet*_*inl 5 .net filesystemwatcher thread-safety

使用共享相同事件处理程序的 FileSystemWatchers 安全吗?

让多个 FileSystemWatcher 使用相同的事件处理程序监视不同的目录是否安全?

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
Run Code Online (Sandbox Code Playgroud)

或者我们必须将 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
Run Code Online (Sandbox Code Playgroud)

这里是 helper 类的用法:

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
Run Code Online (Sandbox Code Playgroud)

Pet*_*hie 3

默认情况下,由 引发的事件FileSystemWatcher是在线程池线程上引发的。这意味着事件处理程序中使用的任何数据都是“共享的”——无论您是否有多个处理程序。您应该保护(例如lock访问)此共享数据以避免损坏。

或者,您可以使用FileSystemWatcher.SynchronizingObject提供同步上下文,以便FileSystemWatcher在单个或已知线程上发生的所有事件。如果您的事件处理程序接触 GUI 元素,通常会执行此操作。