我有一个应用程序,我正在寻找一个文本文件,如果对文件做了任何更改,我使用OnChanged事件处理程序来处理事件。我正在使用NotifyFilters。LastWriteTime,但是事件仍然被触发两次。这是代码。

public void Initialize()
{
   FileSystemWatcher _fileWatcher = new FileSystemWatcher();
  _fileWatcher.Path = "C:\\Folder";
  _fileWatcher.NotifyFilter = NotifyFilters.LastWrite;
  _fileWatcher.Filter = "Version.txt";
  _fileWatcher.Changed += new FileSystemEventHandler(OnChanged);
  _fileWatcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
   .......
}

在我的情况下,OnChanged被调用两次,当我改变文本文件version.txt并保存它。


当前回答

好吧,这是我如何只引发一个事件的解决方案:

FileSystemWatcheк watcher = new FileSystemWatcher();

//'path' - path to the file that has been modified.
watcher.Changed += (s, e) => FileChanged(path);

这里是FileChanged实现

//count is our counter to triger when we can raise and when not.
private int count = 0;
private void FileChanged(string path)
{
   if (count % 2 == 0)
     {
       //code here
     }

     count ++;
}

其他回答

我已经用一个类创建了一个Git repo,该类扩展了FileSystemWatcher,以便仅在复制完成时触发事件。它将丢弃除最后一个事件以外的所有已更改事件,仅在文件可读时才引发该事件。

下载FileSystemSafeWatcher并将其添加到项目中。

然后将其用作普通的FileSystemWatcher并在事件触发时进行监视。

var fsw = new FileSystemSafeWatcher(file);
fsw.EnableRaisingEvents = true;
// Add event handlers here
fsw.Created += fsw_Created;

这里有一个你可以尝试的新解决方案。很适合我。在已更改事件的事件处理程序中,以编程方式从设计器输出中删除处理程序(如果需要的话),然后以编程方式将处理程序添加回来。例子:

public void fileSystemWatcher1_Changed( object sender, System.IO.FileSystemEventArgs e )
    {            
        fileSystemWatcher1.Changed -= new System.IO.FileSystemEventHandler( fileSystemWatcher1_Changed );
        MessageBox.Show( "File has been uploaded to destination", "Success!" );
        fileSystemWatcher1.Changed += new System.IO.FileSystemEventHandler( fileSystemWatcher1_Changed );
    }

如果你注册了OnChanged事件,那么在修改之前删除被监视的文件可能会起作用,只要你只需要监视OnChange事件。

以下是我的解决方案,帮助我阻止事件被提出两次:

watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;

这里我只设置了文件名和大小的NotifyFilter属性。 watcher是FileSystemWatcher的对象。希望这能有所帮助。

我可以通过添加一个函数来检查缓冲区数组中的重复项来做到这一点。

然后使用计时器在数组X时间内未被修改后执行该操作: -每次有东西写入缓冲区时重置计时器 —对tick执行动作

这还捕获了另一种复制类型。如果修改文件夹内的文件,该文件夹也会引发Change事件。

Function is_duplicate(str1 As String) As Boolean
    If lb_actions_list.Items.Count = 0 Then
        Return False
    Else
        Dim compStr As String = lb_actions_list.Items(lb_actions_list.Items.Count - 1).ToString
        compStr = compStr.Substring(compStr.IndexOf("-") + 1).Trim

        If compStr <> str1 AndAlso compStr.parentDir <> str1 & "\" Then
            Return False
        Else
            Return True
        End If
    End If
End Function

Public Module extentions
<Extension()>
Public Function parentDir(ByVal aString As String) As String
    Return aString.Substring(0, CInt(InStrRev(aString, "\", aString.Length - 1)))
End Function
End Module