5

使用 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
4

1 回答 1

3

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

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.

于 2012-09-17T17:44:51.997 回答