1

通过做一些谷歌,我开始知道“它用于跟踪文件系统操作”。但我不明白它的实用性,观察者可以直接触发事件而不将其存储在某个中间缓冲区中!

是否可以将异步事件流(复制/修改文件)转换为同步事件调用?另外,我不确定 FileWatcher 是否异步触发事件。

有人可以对此有所了解吗?

4

4 回答 4

2

我认为,您在问题中错过了缓冲区的要点。

来自MSDN,FileSystemWatcher(强调我的):

Windows 操作系统会将 FileSystemWatcher 创建的缓冲区中的文件更改通知您的组件。如果短时间内有很多变化,缓冲区可能会溢出。这会导致组件丢失对目录更改的跟踪,并且它只会提供一揽子通知。

因此,它不是尚未告诉您的事件缓冲区,而是它为 Windows 提供的缓冲区以首先支持通知,而无需轮询。如果 Windows 在这种情况下抛出大量操作,则此缓冲区将溢出,并且 FileSystemWatcher 的使用者/用户将丢失一些通知。

于 2010-02-02T09:01:32.433 回答
1

The underlying Windows API that makes FileSystemWatcher work is ReadDirectoryChangesW(). Note the 2nd argument, lpBuffer. That's a one-to-one match with the internal buffer whose size you can set with the InternalBufferSize property.

A buffer is required because Windows cannot easily run user code in response to directory changes. These changes are detected by the respective file system drivers, they run in kernel mode. Running user mode code requires an expensive mode switch and a thread context switch, much too expensive to do so for each individual detected change. The buffer is there to collect changes, waiting for the user mode code to start running and empty the buffer.

There's a well documented failure mode for FSW, there could be too many changes to keep up with. You'd see the Error event in managed code. Increasing the buffer size can help, a lot, the default buffer is rather small at 4096 bytes. Making it arbitrary large is not a good idea though, buffer space is also required in the kernel and that's taken from the kernel memory pool. That's a limited resource, gobbling large amounts from the pool affects all programs running on the machine.

于 2010-02-02T13:37:33.497 回答
1

当文件观察器不能一次处理所有请求时,它必须缓冲请求,这主要是由于您编写的代码对 FileSystemwatcher 抛出的事件做出反应。据我所知,FileSystemWatcher 事件不是异步的,但您可以在事件中生成线程以异步处理您的代码。当然,文件系统可以一次更改多个文件,例如删除所有文件或考虑复制粘贴。

我希望这很清楚。

于 2010-02-02T08:58:43.247 回答
0

是的,FileSystemWatcher 用于跟踪文件系统中的更改。它监视一个目录并报告目录中任何文件的以下更改:

  • OnCreated:创建文件或目录时调用
  • OnChanged:当文件或目录改变时调用
  • OnRenamed:重命名文件或目录时调用
  • OnDeleted:删除文件或目录时调用

“内部缓冲区”是操作系统向 FileSystemWatcher 发送信息的方式。它的大小由“InternalBufferSize”属性控制。

如果一次发生太多更改,内部缓冲区可能会填满。然后,您会收到一个更改通知,而不是获取所有单独的更改:

  • OnError:当个别更改因缓冲区溢出而丢失时调用

FileSystemWatcher 确实会异步触发事件。具体来说,只要文件更改,就会触发该事件。

于 2010-02-02T09:15:59.420 回答