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

时间:2008-09-30 04:53:27

标签: .net performance filesystemwatcher

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

我无法写服务在服务器上运行(禁止访问!),因此解决方案必须是客户端的本地解决方案。及时性并不是特别重要。我可以在通知中花费一分钟或更长时间。我正在关注创建,删除,重命名和更改。

使用.NET System.IO.fileSystemWatcher会在服务器上创建大量负载吗?

10个独立的观察者如何减少正在观看的文件夹/文件的数量? (从700个文件夹中减去200个,从总共5500个文件减少到1200个)更多网络流量而不是更少?我的想法是在服务器上重新洗牌,将观看的文件放在1棵树下。我可能并不总是有这个选项,因此是观察者团队。

我认为另一个解决方案是定期检查FSW是否在服务器上造成过度负载,或者它是否适用于一大堆SysAdmin类型的原因。

有更好的方法吗?

7 个答案:

答案 0 :(得分:69)

从服务器负载的角度来看,在您描述的方案中使用IO.FileSystemWatcher进行远程更改通知可能是最有效的方法。它在内部使用FindFirstChangeNotificationReadDirectoryChangesW Win32 API函数,这些函数又以优化的方式与网络重定向器通信(假设使用标准的Windows网络:如果使用第三方重定向器,它不会' t支持所需的功能,事情根本不起作用)。 .NET包装器还使用异步I / O和所有内容,进一步确保最高效率。

此解决方案的唯一问题是它不太可靠。除了必须暂时处理暂时离开的网络连接(这不是太大的问题,因为IO.FileSystemWatcher将在这种情况下触发您可以处理的错误事件),底层机制具有某些基本限制。从Win32 API函数的MSDN文档:

    当缓冲区长度大于64 KB并且应用程序正在通过网络监视目录时,
  • ReadDirectoryChangesW因ERROR_INVALID_PARAMETER而失败。这是由于基础文件共享协议的数据包大小限制

  • 为远程文件系统调用FindFirstChangeNotification时,可能不会返回通知

换句话说:在高负载下(当您需要大缓冲区时),或者更糟糕的是,在随机未指定的情况下,您可能无法获得预期的通知。这甚至是本地文件系统观察者的问题,但它在网络上更是一个问题。 Another question here on SO详细介绍了API的固有可靠性问题。

使用文件系统观察程序时,您的应用程序应该能够处理这些限制。例如:

  • 如果您要查找的文件包含序列号,请存储您收到通知的最后一个序列号,这样您就可以在将来的通知中查找“空白”并处理您没有获得的文件通知;

  • 收到通知后,请始终执行完整目录扫描。这可能听起来很糟糕,但由于扫描是事件驱动的,它仍然比哑巴轮询更有效。此外,只要保留单个目录中的文件总数,以及要扫描的目录数量,大约一千个左右,此操作对性能的影响应该是非常小的。

设置多个听众是你应该尽可能避免的事情:如果有的话,这将使事情更少可靠......

无论如何,如果你绝对使用文件系统观察者,只要你知道这些限制就可以正常工作,并且不希望每个修改过的文件都有1:1的通知/创建。

所以,如果你有其他选择(基本上,让编写文件的过程以非文件系统的方式通知你:任何常规的RPC方法都会有所改进......),那些绝对值得研究可靠性的观点。

答案 1 :(得分:9)

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

然而,现在,我只是将更改推送到队列并在另一个线程上处理队列。这似乎解决了我原来的问题。对于您的问题,您可以让多个观察者进入同一队列。

但是,我没有用你的问题来解决这个问题。

答案 2 :(得分:3)

根据我的经验,FSW不会产生高网络流量。但是,如果存在性能问题,您使用多个观察者并将其分解为更少的正在观看的文件夹的方法听起来是合理的。

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

答案 3 :(得分:2)

MSDN documentation indicates您可以使用FileSystemWatcher组件来监视网络驱动器上的文件系统更改。

它还表示观察程序组件侦听文件系统更改通知,而不是定期询问目标驱动器是否有更改。

基于此,网络流量的数量完全取决于您希望该网络驱动器的内容发生变化的程度。 FSW组件不会增加网络流量。

答案 4 :(得分:1)

Watcher看起来100%可靠 - 只需观察观察者对象上的缓冲区大小。 我已经测试了数千个文件更新,没有丢失。

我建议使用多线程方法 - 触发器是文件监视器。 它可以为检测到的每个文件更改启动一个线程。观察者可以更快地处理 溢出的可能性较小。 (使用异步线程)

答案 5 :(得分:1)

使用System.IO.FileSystemWatcher一段时间之后。它不够稳定,无法处理过快发生的事件。确保100%读取文件。我使用简单的目录方法来搜索文件。阅读后,立即将文件复制到另一个文件夹。将其与正在读取文件时添加的新文件隔离开来。

定时器用于定期读取文件夹。通过将已读取的文件复制到存档文件夹,可确保不会再次读取该文件。随后的读取将始终是新文件。

var fileNames = Directory.GetFiles(srcFolder); foreach(fileNames中的字符串fileName) {    string [] lines = File.ReadAllLines(fileName);

答案 6 :(得分:-1)

我不认为计算机与FSW和正在监视其位置的计算机之间存在任何类型的活动状态或通信。换句话说,FSW没有ping网络操作系统来检查文件。

可以想象,当发生更改时,消息或事件仅 引发/发送到联网的FSW。

但这只是猜测。 :)