System.IO.FileSystemWatcher监视networking服务器文件夹 – 性能注意事项

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

我不能写一个服务在服务器上运行(禁止!),所以解决scheme必须是本地的客户端。 及时性并不特别重要。 我可以忍受延迟一分钟或更长时间的通知。 我正在观看创build,删除,重命名和更改。

使用.NET System.IO.fileSystemWatcher会在服务器上创build多大的负载?

10个独立的观察者如何减less正在观看的文件夹/文件的数量? (从700个文件夹减less到200个,从5500个文件减less到1200个)更多的networkingstream量,而不是更less? 我的想法是在服务器上重新安排观看的文件在1树下。 我可能并不总是有这个选项,所以观察者的团队。

我想另一种解决scheme是定期检查,如果FSW在服务器上创build一个不适当的负载,或者如果它不适用于一大堆SysAdmintypes的原因。

有一个更好的方法吗?

从服务器负载的angular度来看,在描述的场景中使用IO.FileSystemWatcher进行远程更改通知可能是最有效的方法。 它在内部使用FindFirstChangeNotification和ReadDirectoryChangesW Win32 API函数,这些函数又以优化的方式与networkingredirect器进行通信(假设标准的Windowsnetworking:如果使用第三方redirect器,并且不支持所需的function,根本不工作)。 .NET包装也使用asynchronousI / O和一切,进一步确保最大的效率。

这个解决scheme唯一的问题是它不是很可靠。 除了必须处理networking连接临时消失(这不是一个太大的问题,因为IO.FileSystemWatcher会在这种情况下触发一个错误事件,你可以处理),底层机制有一定的基本限制。 从Win32 API函数的MSDN文档:

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

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

换句话说:在高负载下(当你需要一个很大的缓冲区),或者更糟糕的是,在没有指定的情况下,你可能不会收到你期望的通知。 这对本地文件系统观察者来说甚至是一个问题,但是这对networking来说却是一个问题。 另一个关于SO的问题详细介绍了API的固有可靠性问题。

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

  • 如果您要查找的文件具有序列号,请存储您收到通知的最后一个序列号,以便在未来的通知中查找“间隙”,并处理未收到通知的文件。

  • 收到通知后,请始终进行完整的目录扫描。 这可能听起来很糟糕,但由于扫描是事件驱动的,所以它比哑投票更有效率。 另外,只要将文件总数保存在一个目录中,以及要扫描的目录数量不超过一千个,那么这个操作对性能的影响应该是非常小的。

设置多个监听器是你应该尽可能避免的事情:如果有的话,这将使事情变得更加可靠。

无论如何,如果您绝对必须使用文件系统监视器,只要您意识到这些限制,事情就可以正常工作,并且不要指望每个修改/创build的文件都有1:1的通知。

所以,如果你有其他的select(本质上,写入文件的过程以非文件系统的方式通知你:任何常规的RPC方法都将是一个改进…),那么从可靠性点看法。

我已经多次使用C#中的文件系统监视器。 我第一次使用它们时,我遇到了停止工作的问题,主要是因为我正在处理线程中发生变化的事实。

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

但是,我还没有用这种问题的规模。

根据我的经验,FSW不会造成很高的networkingstream量。 但是,如果出现性能问题,那么使用多个观察者并将其分解为更less的文件夹的方法听起来是合理的。

我在networking驱动器上遇到了一些FSW的大问题,但是:删除文件总是抛出错误事件,而不是删除的事件。 我没有find解决scheme,所以我现在避免使用FSW,如果有解决方法…

MSDN文档指出您可以使用FileSystemWatcher组件来监视networking驱动器上的文件系统更改。

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

基于此,networkingstream量的数量完全取决于您期望networking驱动器的内容有多less改变。 FSW组件不会添加到networkingstream量级别。

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

我build议使用multithreading方法 – 触发器是文件观察器。 它可以为检测到的每个文件更改启动一个线程。 观察者可以以更less的溢出机会处理得更快。 (使用asynchronous线程)

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

定时器用于定期读取文件夹。 通过将已读取的文件复制到归档文件夹,确保不会再次读取。 随后的阅读将永远是新的文件。

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

我不认为计算机与FSW和位置被监控的计算机之间有任何活动状态或通信。 换句话说,FSW不是pingnetworking操作系统来检查文件。

人们可以设想,一个消息或事件只有在发生变化时才会向联网的FSW发出/发送。

但这只是猜测。 🙂