处理FileSystemWatcher中的多个更改事件

4

我有以下子程序:

  Private Sub Watcher_Changed(ByVal sender As System.Object, ByVal e As FileSystemEventArgs)
        If Path.GetExtension(e.Name) = ".p2p" Then
            Exit Sub
        Else
            Try
                ' multiple change events can be thrown. Check that file hasn't already been moved.
                While Not File.Exists(e.FullPath)
                    Exit Try
                End While

                ' throw further processing to a BackGroundWorker
                ChangedFullPath = e.FullPath
                ChangedFileName = e.Name

                FileMover = New BackgroundWorker
                AddHandler FileMover.DoWork, New DoWorkEventHandler(AddressOf ProcessFile)
                FileMover.RunWorkerAsync()
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try

        End If
    End Sub

当文件通过FTP上传时,我仍然会收到多个已更改文件的通知。

我想修改"Try"语句,如果在过去的(时间)内发生了更改通知,比如3秒钟内,也将其丢弃。这应该很简单,但由于某种原因今天它没有出现在我的脑海中,而且我也无法理解我在谷歌上找到的答案。

谢谢, 斯科特

7个回答

10
几年前,我创建了一个上传文件到FTP文件夹的服务。以下是我所做的一些事情,这些事情应该能够帮助您解决问题:
  1. 我测试了所有NotifyFilters,并选择了能够剔除重复通知的筛选器(只使用NotifyFilters.Size可以给我每个创建的文件可靠的通知,并减少了几乎所有的重复通知)
  2. 在Watcher_Changed事件中,我忽略了事件参数中包含的文件,只处理当前文件夹中的所有文件;我尝试将文件夹中的所有文件添加到队列中,如果它们已经在队列中,则跳过下面的第三步。
  3. 为每个新发现的唯一文件启动一个新线程;我的线程尝试获取文件的锁,如果无法获取,则表示某些其他进程仍在访问它(正在上传等),因此我的线程会睡眠一段时间后再次尝试。
  4. 当文件完全处理完毕时,线程所做的最后一件事是将其移动到归档文件夹,然后从队列中删除它,以便不会意外地再次处理它。
对我来说,这似乎很有效,直到我离开那份工作,该服务一直可靠地上传文件数个月。

3
我们曾经遇到过类似的情况,但是批量写入文件的系统使用了临时名称,并在完成后将其更改为“真实”名称。你的ftp客户端能否做类似的事情呢?如果可以,那么你可以检查新文件名并通过扩展名或前缀进行检查;如果它不是预期的最终文件名格式,则可以忽略它。

3
我之前遇到过完全相同的情况,最后实现了一个定时器机制来等待文件“稳定”,或者在x时间内停止写入事件。虽然有些笨拙,但是这个方法很有效。

2

需要注意的一点是,访问文件可能会更改文件属性之一,例如“访问时间”等。如果您没有正确设置通知过滤器,则可能会触发另一个事件。


1

我曾经遇到过同样的问题,我正在保存通过代码上传的文件,删除和创建每次都会触发两次。我只需要检查文件是否存在,然后再进行处理。

private void fsw_Created(object sender, FileSystemEventArgs e)
{
   if (File.Exists(e.FullPath))
   {
      //process the file here
   }
}

0

我正在尝试检测Excel文件何时发生更改,但遇到了一个问题,即更改事件未触发,因为我只关心单个文件,所以设置过滤器不起作用。当我删除过滤器并查看触发的事件时,事件参数名称属性似乎是一个随机生成的名称,而不是我知道已更改的特定文件名。

因此,我无法在特定的Excel文件更改时获得简单的通知。


0
今天我在尝试自动重新加载配置文件时遇到了同样的问题。最终,我计算了文件的MD5哈希值,以确定文件是否实际更改,并仅在哈希值不同时重新加载。这是我能够过滤重复项的唯一明确方法。
我曾经考虑过使用定时器机制来过滤更改通知,但像pete-m一样,我觉得这是一个不太干净的解决方案。
我尝试仅监视LastWrite时间更改,但那并没有起作用。我仍然收到了重复的通知。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接