我需要设置一个应用程序来监视在本地或网络驱动器上的目录中创建的文件.
请问FileSystemWatcher
一个计时器或投票将是最好的选择.我过去曾使用过这两种方法,但并不广泛.
两种方法都存在哪些问题(性能,可靠性等)?
我看到文件系统观察器在生产和测试环境中失败了.我现在认为它很方便,但我认为它不可靠.我的模式是使用文件系统观察程序来监视更改,但偶尔进行轮询以捕获丢失的文件更改.
编辑:如果您有用户界面,您还可以让用户"刷新"更改而不是轮询.我会将它与文件系统观察器结合起来.
我遇到的最大问题是当缓冲区满了时丢失文件.很容易修复 - 只需增加缓冲区.请记住,它包含文件名和事件,因此请将其增加到预期的文件数量(试用和错误).它确实使用了无法分页的内存,因此如果内存不足,它可能会强制其他进程进行分页.
这是关于缓冲区的MSDN文章: FileSystemWatcher .. ::.InternalBufferSize属性
每个MSDN:
增加缓冲区大小是昂贵的,因为它来自无法换出到磁盘的非分页内存,因此请尽可能减小缓冲区.要避免缓冲区溢出,请使用NotifyFilter和IncludeSubdirectories属性过滤掉不需要的更改通知.
我们使用16MB,因为一次预计会有大量批次.工作正常,永远不会错过文件.
我们还在开始处理之前读取所有文件,即使只有一个文件...将文件名安全地缓存(在我们的例子中,放入数据库表中)然后处理它们.
对于文件锁定问题,我产生了一个进程,它等待文件解锁等待一秒钟,然后是两秒钟,然后是四个等等.我们从不投票.这已经生产了大约两年没有错误.
的FileSystemWatcher
也可能错过在繁忙时间的变化,如果排队改变的次数溢出提供的缓冲液中.这不是.NET类本身的限制,而是基础Win32基础结构的限制.根据我们的经验,最小化此问题的最佳方法是尽快将通知出列并在另一个线程上处理它们.
如上面的@ChillTemp所述,观察者可能无法处理非Windows共享.例如,它在安装的Novell驱动器上根本不起作用.
我同意一个很好的折衷方案是偶尔进行民意调查,以便找出任何错过的变化.
另请注意,文件系统观察程序在文件共享上不可靠.特别是如果文件共享托管在非Windows服务器上.FSW不应用于任何关键的事情.或者应该与偶尔的民意调查一起使用,以验证它没有遗漏任何东西.
就个人而言,我已经FileSystemWatcher
在生产系统上使用了它,它运行良好.在过去的6个月中,它没有一次性打嗝全天候运行.它正在监视单个本地文件夹(共享).我们必须处理相对较少的文件操作(每天触发10个事件).这不是我曾经不必担心的事情.如果我不得不重新制定决定,我会再次使用它.
我目前使用的FileSystemWatcher
是一个平均每100毫秒更新一次的XML文件.
我发现,只要FileSystemWatcher
配置正确,您就不应该遇到本地文件问题.
我没有远程文件监视和非Windows共享的经验.
我会考虑轮询文件是多余的,不值得花费开销,除非你天生不信任FileSystemWatcher
或直接遇到其他人在这里列出的限制(非Windows共享和远程文件监视).
我在使用FileSystemWatcher
网络共享时遇到了麻烦.如果你在纯Windows环境中,它可能不是问题,但我正在观看NFS共享,因为NFS是无状态的,所以当我正在观看的文件发生变化时,从来没有通知.
我会去投票.
网络问题导致FileSystemWatcher
不可靠(即使在重载错误事件时).