来自MSDN:
Windows 操作系统会通知您的组件在由 FileSystemWatcher 创建的缓冲区中的文件更改。如果短时间内有很多变化,缓冲区可能会溢出。这会导致组件丢失对目录更改的跟踪,并且它只会提供一揽子通知。使用InternalBufferSize属性增加缓冲区的大小是昂贵的,因为它来自无法换出到磁盘的非分页内存,因此请保持缓冲区小而大,以免错过任何文件更改事件。要避免缓冲区溢出,请使用NotifyFilter和IncludeSubdirectories属性,以便您可以过滤掉不需要的更改通知。
如果增加缓冲区大小还不够,并且您无法控制一次触发事件的文件数量,则必须添加额外的轮询。
另请参阅此相关问题:
FileSystemWatcher 在目录中同时添加多个文件时无法正常工作……</a>
更新:
简单地增加缓冲区大小可能很诱人,但这应该小心。事实上,在网络访问方面存在 64k 的限制。该类FileSystemWatcher
ReadDirectoryChangesW
正在使用具有以下限制的 Windows API 函数:
当缓冲区长度大于 64 KB 并且应用程序正在通过网络监视目录时,ReadDirectoryChangesW 失败并显示 ERROR_INVALID_PARAMETER。这是由于底层文件共享协议的数据包大小限制。
如果您想更深入地了解修改缓冲区大小的成本,您应该在这里查看 Microsoft 的 Walter Wang 的帖子:
网络上的 FileSystemWatcher(下面引用的完整帖子)
很抱歉,FileSystemWatcher.InternalBufferSize 的文档在监控网络路径时没有非常清楚地说明缓冲区大小。监控网络路径时建议不要超过64K。
FileSystemWatcher 基本上是 Win32 ReadDirectoryChangesW API 的 .Net 包装器。要使用 ReadDirectoryChangesW,您需要创建并指定一个缓冲区,操作系统将使用更改填充该缓冲区。但是,ReadDirectoryChangesW 文档中没有提到(但在 FileSystemWatcher 文档中暗示)是文件系统创建了一个内部内核缓冲区来临时存储更改信息,直到它有机会更新用户缓冲区。创建的内核缓冲区的大小与在 ReadDirectoryChangesW 中指定的大小相同,并且是在非分页池内存中创建的。每次创建/调用 FileSystemWatcher / ReadDirectoryChangesW 时,也会创建一个新的内核缓冲区。
内核内存池(分页和非分页)在系统地址空间中留出供设备驱动程序和其他内核组件使用。它们根据需要动态增长和收缩。通过转到任务管理器的“性能”选项卡,可以轻松查看池的当前大小。池将动态增长,直到达到最大值,该最大值在引导时计算并取决于可用的系统资源(主要是 RAM)。您不想达到这个最大值,否则各种系统服务和驱动程序将开始失败。然而,这个计算出的最大值并不容易获得。要确定最大池大小,您需要使用内核调试器。如果您对有关系统内存池的更多信息感兴趣,
考虑到这一点,没有关于可以使用什么大小的缓冲区的建议。系统池的当前大小和最大大小将因客户端而异。但是,对于每个 FileSystemWatcher / ReadDirectoryChangesW 缓冲区,您可能不应该超过 64k。这是因为 ReadDirectoryChangesW 中记录的网络访问有 64k 限制。但最终您将不得不在各种预期的目标系统上测试应用程序,以便您可以调整缓冲区。
有与 .Net 应用程序相关的开销,我想 Win32 ReadDirectoryChangesW 程序可能能够在相同的缓冲区大小下实现更好的性能。然而,随着非常快速和大量的文件更改,缓冲区溢出将是不可避免的,并且开发人员将不得不处理发生溢出的情况,例如手动枚举目录以检测更改。
总之,FileSystemWatcher 和 ReadDirectoryChangesW 是一种轻量级的文件更改检测机制,但会有其局限性。Change Journals 是另一种我们认为是中等权重解决方案的机制,但仍然有局限性:
http://msdn.microsoft.com/en-us/library/aa363798%28VS.85%29.aspx
重量级的解决方案是编写一个专用的文件系统过滤器驱动程序,该驱动程序位于文件系统堆栈中并监视文件系统更改。当然,这将是最复杂的方法。大多数病毒扫描程序、备份软件和文件系统监视实用程序(例如 filemon (www.sysinternals.com))都实现了过滤器驱动程序。
我希望以上解释可以帮助您了解您遇到的问题的根本原因。请回复让我们知道您是否需要更多信息。谢谢你。