代码之家  ›  专栏  ›  技术社区  ›  CAD bloke

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

  •  39
  • CAD bloke  · 技术社区  · 17 年前

    我想查看网络服务器上的文件夹树是否有更改。这些文件都有特定的扩展名。树上有大约200个文件夹和大约1200个文件,扩展名是我正在查看的。

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

    使用.NET System.IO.FileSystemWatcher会在服务器上产生很大的负载吗?

    10个独立的监视程序如何减少监视的文件夹/文件的数量?(从700个文件夹减少到200个,从5500个文件减少到1200个)更多的网络流量而不是更少?我的想法是在服务器上进行重组,将被监视的文件放在一棵树下。我可能并不总是有这样的选择,因此观察小组。

    我认为另一个解决方案是定期检查FSW是否在服务器上创建了不适当的负载,或者是否由于一系列系统管理类型的原因而无法工作。

    有更好的方法吗?

    7 回复  |  直到 7 年前
        1
  •  69
  •   Siderite Zackwehdex    7 年前

    从服务器加载的角度,使用 IO.FileSystemWatcher 对于场景中的远程更改通知,您描述的方法可能是最有效的方法。它使用 FindFirstChangeNotification ReadDirectoryChangesW win32 api内部函数,它反过来以优化的方式与网络重定向器通信(假设使用标准的Windows网络:如果使用第三方重定向器,但它不支持所需的功能,则完全无法工作)。.NET包装器还使用异步I/O和所有东西,进一步确保了最大的效率。

    这个解决方案的唯一问题是它不太可靠。除了必须临时处理掉网络连接(这不是太大的问题,因为io.filesystemwatcher在这种情况下会触发一个可以处理的错误事件),底层机制还有一些基本限制。从win32 api函数的msdn文档中:

    • ReadDirectoryChangesW 当缓冲区长度大于64 kb且应用程序正在通过网络监视目录时,失败,错误为\无效\参数。这是由于底层文件共享协议的数据包大小限制造成的。

    • 调用时不能返回通知 FindFirstChangeNotification 对于远程文件系统

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

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

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

    • 收到通知后,始终进行完整的目录扫描。这听起来可能很糟糕,但是由于扫描是事件驱动的,所以它仍然比愚蠢的轮询更有效。另外,只要将单个目录中的文件总数以及要扫描的目录数保持在1000个左右,那么此操作对性能的影响应该是非常小的。

    设置多个监听器是您应该尽可能避免的事情:如果有的话,这将使事情变得均匀 较少的 可靠的…

    不管怎样,如果你真的 要使用文件系统监视程序,只要您知道这些限制,事情就可以正常工作,并且不要期望每个修改/创建的文件都有1:1的通知。

    因此,如果您有其他的选择(本质上,让编写文件的过程以一种非基于文件系统的方式通知您:任何常规的RPC方法都将是一种改进…),那么从可靠性的角度来看,这些绝对值得研究。

        2
  •  9
  •   Nick Randell    17 年前

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

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

    但是,我没有用这个来衡量你的问题。

        3
  •  3
  •   Treb    17 年前

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

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

        4
  •  2
  •   Jim Burger    17 年前

    这个 MSDN documentation indicates 可以使用filesystemwatcher组件监视网络上的文件系统更改 开车 .

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

    基于此,网络流量的大小完全取决于您对该网络驱动器内容的期望变化程度。FSW组件不会添加到网络流量级别。

        5
  •  1
  •   davidWazy    11 年前

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

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

        6
  •  1
  •   trevorwong77    10 年前

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

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

    var filename=directory.getfiles(srcfolder); foreach(文件名中的字符串文件名) { string[]lines=file.readalllines(文件名);

        7
  •  -1
  •   core    17 年前

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

    我们可以想象一个消息或事件是 只有 发生更改时引发/发送到网络FSW。

    但这都只是猜测。:)

    推荐文章