FileSystemWatcher vs轮询来监视文件的变化

我需要设置一个应用程序来监视目录中创建的文件,无论是本地还是网络驱动器。

FileSystemWatcher或者定时器上的轮询将是最好的选择。 过去我使用过这两种方法,但没有广泛使用。

两种方法都有哪些问题(性能,可靠性等)?

我看到文件系统监视器在生产和测试环境中失败。 我现在认为这是一个方便,但我不认为它可靠。 我的模式一直在观察文件系统观察者的变化,但是偶尔轮询以捕捉丢失的文件变化。

编辑:如果你有一个用户界面,你也可以给你的用户“刷新”而不是轮询的能力。 我会结合这个文件系统观察者。

我遇到的最大问题是缓冲区满了时丢失文件。 易于修复 – 只需增加缓冲区。 请记住,它包含文件名和事件,所以将其增加到预期的文件数量(试错)。 它确实使用了无法分页的内存,因此如果内存不足,可能会强制其他进程分页。

这是关于缓冲区的MSDN文章: FileSystemWatcher .. ::。InternalBufferSize属性

每个MSDN:

增加缓冲区的大小是非常昂贵的,因为它来自不能换出到磁盘的非分页内存,所以尽可能的减小缓冲区。 为了避免缓冲区溢出,请使用NotifyFilter和IncludeSubdirectories属性来过滤不需要的更改通知。

我们使用16MB由于一次预期的大批量。 工作正常,永远不会错过一个文件。

在开始处理一个文件之前,我们还读取所有文件…将文件名安全地缓存(在我们的例子中,放到数据库表中)然后处理它们。

对于文件锁定问题,我产生了一个等待文件解锁的过程,等待一秒钟,然后是两个,然后是四个等等。 我们从不投票。 这已经在大约两年的生产没有错误。

如果排队更改的数量超出所提供的缓冲区, FileSystemWatcher也可能错过繁忙时间的更改。 这不是.NET类本身的限制,而是底层Win32基础结构的限制。 根据我们的经验,最大限度地减少这个问题的方法是尽快出列通知,并在另一个线程上处理它们。

正如上面提到的@ChillTemp,观察者可能无法在非Windows共享上工作。 例如,它在安装的Novell驱动器上完全不起作用。

我同意,一个很好的妥协是做一个偶尔的民意调查来弥补任何错过的变化。

另请注意,文件系统监视器在文件共享上不可靠。 特别是如果文件共享托管在非Windows服务器上。 FSW不应该用于任何关键的事情。 或者应该偶尔进行民意调查,以确认它没有遗漏任何东西。

就我个人而言,我在生产系统上使用了FileSystemWatcher ,并且工作得很好。 在过去的六个月里,它没有一次24×7的呃逆。 它正在监视一个本地文件夹(这是共享的)。 我们需要处理的文件操作数量相对较少(每天触发10个事件)。 这不是我曾经担心的事情。 如果我不得不重做决定,我会再次使用它。

我目前在每100毫秒平均更新的XML文件上使用FileSystemWatcher

我发现只要FileSystemWatcher配置正确,就不会有本地文件的问题。

我没有关于远程文件监视和非Windows共享的经验。

我会考虑轮询文件是多余的,不值得的开销,除非你本质上不信任FileSystemWatcher或直接经历了其他人在这里列出的限制(非Windows共享和远程文件监视)。

我会去投票。

网络问题导致FileSystemWatcher不可靠(甚至在重载错误事件时)。

我在网络共享上使用FileSystemWatcher遇到了麻烦。 如果你在一个纯粹的Windows环境中,这可能不是问题,但是我正在看一个NFS共享,而且由于NFS是无状态的,所以当我正在观看的文件发生变化时,从来没有通知过。

我在网络驱动器上遇到了一些FSW的大问题:删除文件总是抛出错误事件,而不是删除的事件。 我没有找到解决方案,所以我现在避免了FSW和使用轮询。

另一方面创建事件工作正常,所以如果你只需要注意文件创建,你可以去FSW。

另外,我本地文件夹上没有任何问题,不管共享与否。

使用FSW 轮询是浪费时间和资源,在我看来,我很惊讶有经验的开发人员建议。 如果您需要使用轮询来检查是否有任何“FSW未命中”,那么您自然可以放弃FSW并仅使用轮询。

目前,我正在试图决定是否将使用FSW 轮询我开发的项目。 阅读答案,很明显,在某些情况下,FSW可以完美地满足需求,而其他时候则需要轮询。 不幸的是, 没有答案实际上处理性能差异(如果有的话),只有“可靠性”问题。 有没有人可以回答这个问题的一部分?

编辑:nmclean的使用FSW和轮询的有效性的观点(你可以阅读在评论中的讨论,如果你感兴趣)似乎是一个非常合理的解释,为什么可以有使用FSW和轮询的情况高效。 谢谢你为我(和其他任何有相同意见的人) 阐明这一点nmclean

用于处理创建事件而不是更改的工作解决方案

即使复制,剪切,粘贴,移动。

 class Program { static void Main(string[] args) { string SourceFolderPath = "D:\\SourcePath"; string DestinationFolderPath = "D:\\DestinationPath"; FileSystemWatcher FileSystemWatcher = new FileSystemWatcher(); FileSystemWatcher.Path = SourceFolderPath; FileSystemWatcher.IncludeSubdirectories = false; FileSystemWatcher.NotifyFilter = NotifyFilters.FileName; // ON FILE NAME FILTER FileSystemWatcher.Filter = "*.txt"; FileSystemWatcher.Created +=FileSystemWatcher_Created; // TRIGGERED ONLY FOR FILE GOT CREATED BY COPY, CUT PASTE, MOVE FileSystemWatcher.EnableRaisingEvents = true; Console.Read(); } static void FileSystemWatcher_Created(object sender, FileSystemEventArgs e) { string SourceFolderPath = "D:\\SourcePath"; string DestinationFolderPath = "D:\\DestinationPath"; try { // DO SOMETING LIKE MOVE, COPY, ETC File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name); } catch { } } } 

此文件观察器的解决方案,而使用静态存储的文件属性更改事件

 class Program { static string IsSameFile = string.Empty; // USE STATIC FOR TRACKING static void Main(string[] args) { string SourceFolderPath = "D:\\SourcePath"; string DestinationFolderPath = "D:\\DestinationPath"; FileSystemWatcher FileSystemWatcher = new FileSystemWatcher(); FileSystemWatcher.Path = SourceFolderPath; FileSystemWatcher.IncludeSubdirectories = false; FileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite; FileSystemWatcher.Filter = "*.txt"; FileSystemWatcher.Changed += FileSystemWatcher_Changed; FileSystemWatcher.EnableRaisingEvents = true; Console.Read(); } static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e) { if (e.Name == IsSameFile) //SKIPS ON MULTIPLE TRIGGERS { return; } else { string SourceFolderPath = "D:\\SourcePath"; string DestinationFolderPath = "D:\\DestinationPath"; try { // DO SOMETING LIKE MOVE, COPY, ETC File.Copy(e.FullPath, DestinationFolderPath + @"\" + e.Name); } catch { } } IsSameFile = e.Name; } } 

这是针对此多重触发事件的解决方法。

我会说使用轮询,尤其是在TDD方案中,因为更容易模拟/存根文件的存在,否则当轮询事件被触发时比依赖更多的“不受控制”的fsw事件更容易。 +的工作在一些受fsw错误困扰的应用程序。

Interesting Posts