为什么FileSystemWatcher会触发两次

Hel*_*rld 8 vb.net filesystemwatcher visual-studio-2010

为什么FileSystemWatcher会触发两次?有没有一种简单的方法来解决它?当然,如果我更新或编辑文本文件,它应该只触发一次?

这个链接在这里http://weblogs.asp.net/ashben/archive/2003/10/14/31773.aspx

  1. 引发两次的事件 - 如果明确指定了事件处理程序(AddHander FSW.Created,AddressOf FSW_Created),则会引发两次事件.这是因为,默认情况下,公共事件会自动调用相应的受保护方法(OnChanged,OnCreated,OnDeleted,OnRenamed).要解决此问题,只需删除显式事件处理程序(AddHandler ...).

"删除显式事件处理程序"是什么意思?

Imports System.IO

Public Class Form2

    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed

        'this fires twice
        MessageBox.Show("test")

    End Sub

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        FileSystemWatcher1.Path = "C:\Users\c\Desktop\test\"
        FileSystemWatcher1.NotifyFilter = NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName Or NotifyFilters.DirectoryName Or NotifyFilters.CreationTime

        FileSystemWatcher1.IncludeSubdirectories = False
        FileSystemWatcher1.Filter = "text.txt"

    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

Arr*_*row 8

更新:

我想出了两个解决方案.一个使用Threads,另一个不使用.请你选择:-).

没有线程:

Imports System.IO

Public Class Form1
    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed
        Dim watcher As System.IO.FileSystemWatcher = sender
        watcher.EnableRaisingEvents = False

        'Do work here while new events are not being raised.
        MessageBox.Show("Test")

        watcher.EnableRaisingEvents = True 'Now we can begin watching for new events.

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        FileSystemWatcher1.Path = "C:\Users\c\Desktop\test"
        FileSystemWatcher1.NotifyFilter = NotifyFilters.LastWrite
        FileSystemWatcher1.IncludeSubdirectories = False
        FileSystemWatcher1.Filter = "test.txt"


    End Sub

    Private Sub FileSystemWatcher_OnChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

此解决方案(没有线程)将watcher.EnableRaisingEvents设置为False.在此之后,您通常会处理受影响(或更改)的任何文件.然后,在完成工作后,它会将EnableRaisingEvents设置为True.

使用线程:

Imports System.IO

Public Class Form1
    Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed
        FileSystemWatcher1.EnableRaisingEvents = False
        Threading.Thread.Sleep(250)
        FileSystemWatcher1.EnableRaisingEvents = True


        MessageBox.Show("test")


    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        FileSystemWatcher1.Path = "C:\Users\c\Desktop\test"
        FileSystemWatcher1.NotifyFilter = NotifyFilters.LastWrite
        FileSystemWatcher1.IncludeSubdirectories = False
        FileSystemWatcher1.Filter = "test.txt"


    End Sub

    Private Sub FileSystemWatcher_OnChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

这个解决方案,虽然有点hacky,确实有效.它会禁用检查250ms的新更改/事件,然后根据您不需要每250ms检查一次更改的假设重新启用检查.我已经尝试了几乎所有我能想到的东西来为你找到一个真正的解决方案,但这将同时起作用.