【发布时间】:2010-02-02 08:50:33
【问题描述】:
通过谷歌搜索,我了解到“它用于跟踪文件系统操作”。但我不明白它的实用性,观察者可以直接触发事件而不将其存储在某个中间缓冲区中!!
是否可以将异步事件流(复制/修改文件)转换为同步事件调用?另外,我不确定 FileWatcher 是否异步触发事件。
有人可以解释一下吗?
【问题讨论】:
标签: c# .net filesystemwatcher
通过谷歌搜索,我了解到“它用于跟踪文件系统操作”。但我不明白它的实用性,观察者可以直接触发事件而不将其存储在某个中间缓冲区中!!
是否可以将异步事件流(复制/修改文件)转换为同步事件调用?另外,我不确定 FileWatcher 是否异步触发事件。
有人可以解释一下吗?
【问题讨论】:
标签: c# .net filesystemwatcher
我认为,您在问题中错过了缓冲区的要点。
来自MSDN, FileSystemWatcher(强调我的):
Windows 操作系统会通知您的文件组件 由创建的缓冲区中的更改 文件系统观察器。如果有很多 短时间内的变化,缓冲 可以溢出。这导致 组件失去对变化的跟踪 目录,它只会 提供一揽子通知。
因此,它不是尚未告诉您的事件缓冲区,而是它为 Windows 提供的缓冲区以首先支持通知,而无需轮询。如果 Windows 在此实例中抛出大量操作,则此缓冲区将溢出,并且 FileSystemWatcher 的使用者/用户将丢失一些通知。
【讨论】:
使 FileSystemWatcher 工作的底层 Windows API 是 ReadDirectoryChangesW()。注意第二个参数 lpBuffer。这是与内部缓冲区的一对一匹配,您可以使用 InternalBufferSize 属性设置其大小。
需要缓冲区,因为 Windows 无法轻松运行用户代码以响应目录更改。这些更改由各自的文件系统驱动程序检测到,它们在内核模式下运行。运行用户模式代码需要昂贵的模式切换和线程上下文切换,对于每个检测到的更改来说这样做成本太高。缓冲区用于收集更改,等待用户模式代码开始运行并清空缓冲区。
FSW 有一个有据可查的故障模式,可能有太多变化无法跟上。您会在托管代码中看到错误事件。增加缓冲区大小会很有帮助,默认缓冲区很小,只有 4096 字节。但是,让它任意大并不是一个好主意,内核中也需要缓冲区空间,并且是从内核内存池中获取的。这是一种有限的资源,从池中大量吞食会影响机器上运行的所有程序。
【讨论】:
当文件观察器不能同时处理所有请求时,它必须缓冲请求,这主要是由于您编写的代码对 FileSystemwatcher 抛出的事件作出反应。据我所知,FileSystemWatcher 事件不是异步的,但您可以在事件中生成线程以异步处理您的代码。当然,文件系统可以一次更改多个文件,比如删除所有文件或考虑复制粘贴。
我希望这很清楚。
【讨论】:
是的,FileSystemWatcher 用于跟踪文件系统中的更改。它监视一个目录并报告目录中任何文件的以下更改:
“内部缓冲区”是操作系统向 FileSystemWatcher 发送信息的方式。它的大小由“InternalBufferSize”属性控制。
如果一次发生太多更改,内部缓冲区可能会被填满。然后,您会收到一个更改通知,而不是获取所有单独的更改:
FileSystemWatcher 确实会异步触发事件。具体来说,只要文件更改,就会触发该事件。
【讨论】: