增加FileSystemWatcher.InternalBufferSize是否真的那么昂贵?

时间:2012-12-17 15:03:43

标签: c# .net performance filesystemwatcher

我正在使用FileSystemWatcher来监控文件夹中的更改,但是一旦我在短时间内进行了几百次修改,我会错过其中一些因为内部缓冲区溢出。所以我想增加InternalBufferSize(我知道它不会真正解决问题,但会降低它的可能性),但我在documentation中看到了这个警告:

  

然而,增加缓冲区大小是昂贵的,因为它来自   非分页内存,无法换出磁盘,所以请保持   缓冲尽可能小。

所以我的问题是:它真的重要吗?今天大多数计算机都有至少1GB的RAM,所以在我看来,如果我将缓冲区大小设置为1MB(而不是默认的8KB),那么1MB不能换成磁盘就不重要了。或者我错过了什么?我不太了解低级别的内容,例如分页/非分页内存,所以我不确定会有什么影响......

3 个答案:

答案 0 :(得分:18)

分配缓冲区的内存当然是一种宝贵的资源。 Windows不会处理内存池耗尽,驱动程序将随机启动失败。池的大小是动态设置的(但可以更改),取决于可用RAM的大小。

FSW要求的默认缓冲区大小为8192字节。在现代机器上并不多。底层的winapi功能不允许您要求超过64KB。一个条目是缓冲区是12个字节加上文件路径的长度乘以2个。更糟糕的情况是在缓冲区用完之前8192 /(12 + 260 * 2)= 15个通知。除非您监视整个驱动器或在您正在观看的目录中拥有非常高的磁盘流量,否则这应该在大多数情况下都可以正常工作。在这种情况下,要求更大的缓冲是公平的。没有黄金公式,请确保实现FileSystemWatcher.Error事件,以便知道您有缓冲区问题。

在大多数实际情况中,您需要仔细处理FSW事件。当进程仍然锁定文件时,它们将被引发。因此,打开或复制文件等操作很麻烦。您可以通过将通知放在线程安全队列上并使用另一个线程尝试获取文件锁定(如有必要)重复处理。现在,这样的队列自动也是快速清空缓冲区的好方法。你现在唯一要注意的是,队列不会超出合理的比例,这会使你的程序崩溃,而是OOM。

答案 1 :(得分:3)

非分页内存的大小有限(更新:Windows的现代版本没有以前版本那样严格的限制,内存量现在是一个灵活的值,取决于Windows可用的整体RAM)和对于内核模式的居民(设备驱动程序,操作系统本身)非常重要。在没有严格控制的情况下使用它会很快导致系统不稳定,更糟糕的是,你不会发现导致这种不稳定的原因。

另外,正如评论所示,重要的不是缓冲区大小,而是从缓冲区中删除数据的速度。

在大多数情况下,文件系统过滤器驱动程序比FileSystemWatcher做得更好。好处是您可以拥有所需的任何日志缓冲区(因为您可以在任何需要的内存中创建它而不受非分页内存的限制),并且您可以在事件发生时处理事件,而不是在事件发生之后。此外,您可以使用比FileSystemWatcher更精细的粒度过滤请求。

答案 2 :(得分:3)

考虑使用消费者生产者设计来读取FileSystemWatcher事件。

BlockingCollection Overview

如果您有一些FileSystemWatcher事件,则无需处理,然后快速解除它们 或者,如果某些人可以比其他人更快地处理,则可以使用单独的集合来保持总计数。