5

同じイベント ハンドラを共有する 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

それとも、イベント ハンドラーをスレッド セーフにするために、次のようなクラスで 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破損を防ぐために、この共有データを保護(アクセスなど)する必要があります。

または、FileSystemWatcher.SynchronizingObjectを使用して同期コンテキストを提供し、FileSystemWatcher発生したすべてのイベントが単一のスレッドまたは既知のスレッドで発生するようにすることもできます。これは通常、イベントハンドラーがGUI要素に触れる場合に行われます。

于 2012-09-17T17:44:51.997 に答える