System.IO.FileSystemWatcher监视网络服务器文件夹-性能注意事项

时间:2020-03-06 14:54:28  来源:igfitidea点击:

我想查看网络服务器上的文件夹树以进行更改。这些文件都有特定的扩展名。树中大约有200个文件夹,带有我正在观看的扩展名的大约1200个文件。

我无法编写要在服务器上运行的服务(超限!),因此解决方案必须在客户端本地。及时性不是特别重要。我可以忍受一分钟或者更长时间的通知延迟。我正在监视创建,删除,重命名和更改。

使用.NET System.IO.fileSystemWatcher是否会在服务器上造成很大的负载?

如何减少10个单独的观察者来减少正在监视的文件夹/文件的数量? (从700个文件夹减少到200个,从5500个文件减少到1200个)更多的网络流量,而不是更少?我的想法是对服务器进行改组,以将监视的​​文件放在一棵树下。我可能并不总是拥有此选项,因此观察员团队需要这样做。

我想另一种解决方案是定期检查FSW是否在服务器上创建了不适当的负载,或者由于一堆SysAdmin类型的原因而无法正常工作。

有一个更好的方法吗?

解决方案

我认为带有FSW的计算机与正在监视其位置的计算机之间不会存在任何活动状态或者通信。换句话说,FSW不会对网络操作系统执行ping操作以检查文件。

可以想象,只有发生更改时,消息或者事件才会引发/发送到联网的FSW。

但这仅仅是猜测。 :)

MSDN文档指示我们可以使用FileSystemWatcher组件来监视网络驱动器上的文件系统更改。

它还指示监视程序组件侦听文件系统更改通知,而不是定期询问目标驱动器以进行更改。

基于此,网络流量的大小完全取决于我们希望该网络驱动器的内容更改多少。 FSW组件不会增加网络流量级别。

从服务器负载的角度来看,在我们描述的方案中使用IO.FileSystemWatcher进行远程更改通知可能是最有效的方法。它在内部使用FindFirstChangeNotification和ReadDirectoryChangesW Win32 API函数,进而以一种优化的方式与网络重定向器进行通信(假定标准Windows网络:如果使用了第三方重定向器,并且它不支持所需的功能,那么将会成功根本不起作用)。 .NET包装器还使用异步I / O和所有其他功能,从而进一步确保了最高效率。

该解决方案的唯一问题是它不是很可靠。除了必须处理暂时无法连接的网络连接(这不是太大的问题,因为在这种情况下IO.FileSystemWatcher会引发错误事件,我们可以处理)之外,底层机制还具有某些基本限制。从有关Win32 API功能的MSDN文档中:

  • 当缓冲区长度大于64 KB并且应用程序正在监视网络上的目录时,ReadDirectoryChangesW失败,并显示ERROR_INVALID_PARAMETER。这是由于基础文件共享协议的数据包大小限制所致
  • 为远程文件系统调用FindFirstChangeNotification时,可能不会返回通知

换句话说:在高负载下(当我们需要大缓冲区时),或者更糟的是,在随机未指定的情况下,我们可能无法获得预期的通知。对于本地文件系统观察者来说,这甚至是一个问题,但更多的是网络上的问题。关于SO的另一个问题是API固有的可靠性问题。

使用文件系统监视程序时,应用程序应该能够应对这些限制。例如:

  • 如果我们要查找的文件具有序列号,请存储上一次收到通知的序列号,以便我们可以在以后的通知中查找"空白",并处理未收到通知的文件;
  • 收到通知后,请始终进行完整目录扫描。这听起来确实很糟糕,但是由于扫描是事件驱动的,因此它仍然比哑轮询更有效。另外,只要将文件总数以及要扫描的目录数保持在1000个左右,该操作对性能的影响无论如何应该很小。

设置多个侦听器是我们应尽可能避免的事情:如果有的话,这会使事情变得更加不可靠...

无论如何,如果我们绝对必须使用文件系统监视程序,那么只要我们了解这些限制,一切就可以正常进行,并且不要期望对每个修改/创建的文件都发出1:1通知。

因此,如果我们还有其他选择(本质上说,让写文件的过程以非文件系统的方式通知我们:任何常规的RPC方法都会有所改进...),那么从可靠性角度来看,这些绝对值得研究观点。

我已经使用了Ca多次的文件系统观察程序。第一次使用它们时,我在停止工作时遇到了问题,主要是因为我正在处理报告更改的线程中的更改。

但是现在,我只是将更改推送到队列中,然后在另一个线程上处理该队列。这似乎解决了我最初遇到的问题。对于问题,我们可以让多个观察者推送到同一队列中。

但是,我还没有将这种方法用于我们遇到的各种问题。

以我的经验,FSW不会产生很高的网络流量。但是,如果存在性能问题,则使用多个监视程序并将其分解为要监视的较少文件夹的方法听起来很合理。

但是,我在网络驱动器上的FSW遇到了一些大问题:删除文件始终会引发错误事件,而不会引发已删除事件。我没有找到解决方案,因此如果可以解决的话,我现在避免使用FSW ...