FileSystemWatcher和Windows 7 [英] FileSystemWatcher and windows 7
问题描述
我正在编写一个监视网络目录的工具,该工具正在Windows Server 2008计算机上运行,任何未使用Windows 7的计算机都会从网络驱动器上放置的文件中正确触发FileSystemWatcher的OnChanged事件,由于某种原因,如果在一台Windows 7计算机上一次复制的文件量大于19,则不会触发任何事件,尽管如果单独完成文件也可以.是否有解决方法,或者Windows 7内核如何处理FSW事件?
I am writing a tool that monitors a network directory and is running off of a Windows Server 2008 machine, the OnChanged event for the FileSystemWatcher is being fired correctly from files placed on the network drive by any computer that is not using Windows 7, for some reason if the amount of files copied is more than 19 on a windows 7 computer (at once) then no events are fired although it works if files are done individually. Is there a workaround for this or is that just how the Windows 7 kernel behaves with FSW events?
只是为了说明它从XP机器复制时可以处理数千个文件. (该软件仍在2008服务器上).
Just to clarify it works for thousands of files when copied from an XP machine. (The software is still on the 2008 server machine).
推荐答案
来自
Windows操作系统在FileSystemWatcher创建的缓冲区中将文件更改通知组件.如果在短时间内有很多更改,则缓冲区可能会溢出.这将导致该组件无法跟踪目录中的更改,它将仅提供一揽子通知.使用 InternalBufferSize 属性是昂贵的,因为它来自无法调换到磁盘的非分页内存,因此请使缓冲区既小又足够大,以免丢失任何文件更改事件.为避免缓冲区溢出,请使用 NotifyFilter 和 IncludeSubdirectories 属性,以便进行过滤发出不需要的更改通知.
The Windows operating system notifies your component of file changes in a buffer created by the FileSystemWatcher. If there are many changes in a short time, the buffer can overflow. This causes the component to lose track of changes in the directory, and it will only provide blanket notification. Increasing the size of the buffer with the InternalBufferSize property is expensive, as it comes from non-paged memory that cannot be swapped out to disk, so keep the buffer as small yet large enough to not miss any file change events. To avoid a buffer overflow, use the NotifyFilter and IncludeSubdirectories properties so you can filter out unwanted change notifications. 如果增加缓冲区大小还不够,并且您无法控制一次有多少文件触发事件,则必须添加其他轮询. If increasing the buffer size is not sufficient and you cannot control how many files are triggering events at a time you would have to add additional polling. 另请参阅以下相关问题: See also this related question: 更新: 仅增加缓冲区大小可能很诱人,但应谨慎进行.实际上,在网络访问方面存在64k的限制. It might be tempting to simply increase the buffer size but this should be done with care. In fact, there is a 64k limitation when it comes to network access. The ReadDirectoryChangesW失败,并显示ERROR_INVALID_PARAMETER.这是由于基础文件共享协议对数据包大小的限制. ReadDirectoryChangesW fails with ERROR_INVALID_PARAMETER when the buffer length is greater than 64 KB and the application is monitoring a directory over the network. This is due to a packet size limitation with the underlying file sharing protocols. 如果您想对修改缓冲区大小的成本有更深入的了解,可以在这里查看Microsoft的Walter Wang的帖子: If you want to get a deeper understanding on the cost of modifying the buffer size you should have a look at the post of Walter Wang of Microsoft here: 跨网络的FileSystemWatcher (全文引述如下) FileSystemWatcher across the network (full post quoted below) 对不起,有关
FileSystemWatcher.InternalBufferSize
并没有明确说明
监视网络时的缓冲区大小
小路.建议不要超过64K
监视网络路径时. I'm sorry that the documentation of
FileSystemWatcher.InternalBufferSize
didn't state very clear about the
buffer size when monitoring network
path. It's recommended not exceeds 64K
when monitoring network path. FileSystemWatcher基本上是一个.Net
Win32的包装器
ReadDirectoryChangesW API.使用
ReadDirectoryChangesW,您创建并
指定操作系统将要使用的缓冲区
填充更改.然而,
没有提到的
ReadDirectoryChangesW文档
(但在
FileSystemWatcher docs)是
文件系统创建内部内核
缓冲区,用于存储更改信息
暂时直到有机会
更新用户缓冲区.的大小
创建的内核缓冲区是
与在中指定的尺寸相同
ReadDirectoryChangesW并创建
在非分页的池内存中.每次
FileSystemWatcher/
ReadDirectoryChangesW已创建/
被称为,一个新的内核缓冲区
已创建. FileSystemWatcher is basically a .Net
wrapper for the Win32
ReadDirectoryChangesW API. To use
ReadDirectoryChangesW, you create and
specify a buffer that the OS will
populate with the changes. However,
what is not mentioned in the
ReadDirectoryChangesW documentation
(but is hinted in the
FileSystemWatcher docs) is that the
file system creates an internal kernel
buffer to store the change information
temporarily until it has the chance to
update the user buffer. The size of
the kernel buffer that is created is
the same size that is specified in
ReadDirectoryChangesW and is created
in non-paged pooled memory. Every time
a FileSystemWatcher /
ReadDirectoryChangesW is created /
called, a new kernel buffer is also
created. 内核内存池(分页和
非分页)在系统中被保留
设备驱动程序的地址空间和
其他要使用的内核组件.他们
随着
必要的.当前大小
通过转到
任务的性能"选项卡
经理.游泳池会长大
动态地直到它们达到最大
在启动时计算的值
并取决于可用的系统
资源(主要是RAM).你不
想达到这个最大值,否则
各种系统服务和驱动程序
将开始失败.但是这个
计算出的最大值不容易
可用的.确定最大
池大小,您需要使用内核
调试器.如果您有兴趣
有关系统的更多信息
内存池,我建议您
看看MSPress书中的第7章
在Windows 2000中,所罗门和
鲁西诺维奇. The kernel memory pools (paged and
non-paged) are set aside in the system
address space for device drivers and
other kernel components to use. They
grow and shrink dynamically as
necessary. The current size of the
pools can be easily seen by going to
the Performance tab of the Task
Manager. The pools will grow
dynamically until they hit a maximum
value which is calculated at boot time
and depends on available system
resources (mostly RAM). You do not
want to hit this maximum value or else
various system services and drivers
will start failing. However, this
calculated maximum value is not easily
available. To determine the maximum
pool sizes, you need to use a kernel
debugger. If you are interested in
further information about the system
memory pools, I recommend that you
look at Chapter 7 in the MSPress book
Inside Windows 2000 by Solomon and
Russinovich. 牢记这一点,没有
关于什么大小的缓冲区的建议
您可以使用.当前和最大值
系统池的大小将
因客户而异.
但是,您可能不应该去
每个FileSystemWatcher超过64k/
ReadDirectoryChangesW缓冲区.这
源于以下事实:
网络访问权限限制为64k
在ReadDirectoryChangesW中记录.
但是最后你将拥有
在各种情况下测试应用程序
预期目标系统,以便您
可以调整您的缓冲区. With this in mind, there is no
recommendation on what size buffers
you can use. The current and maximum
size of the system pools are going to
be varied from client to client.
However, you probably should not go
over 64k for each FileSystemWatcher /
ReadDirectoryChangesW buffer. This
stems from the fact that there is a
64k limitation with network access as
documented in ReadDirectoryChangesW.
But in the end you are going to have
to test the application on a variety
of expected target systems so that you
can tune your buffer. .Net有相关的开销
应用程序,我想一个
Win32 ReadDirectoryChangesW程序
也许能够取得更好的成绩
相同缓冲区大小的性能.
但是,速度非常快,而且数量众多
文件更改,缓冲区溢出将是
不可避免的,开发商正在走向
不得不处理案件时
发生超车,例如手动
枚举要检测的目录
变化. There is overhead associated with .Net
applications and I imagine that a
Win32 ReadDirectoryChangesW program
might be able to achieve better
performance with the same buffer size.
However, with very fast and numerous
file changes, buffer overruns will be
inevitable and the developer is going
to have to handle the case when an
overrun occurs such as manually
enumerating the directory to detect
the changes. 最后,FileSystemWatcher和
ReadDirectoryChangesW是一个
轻量级文件更改检测
将会有它的机制
局限性.现更改日记"为
我们将要使用的另一种机制
考虑中等重量的解决方案,但是
仍然会有局限性: In conclusion, FileSystemWatcher and
ReadDirectoryChangesW are a
lightweight file change detection
mechanism that is going to have its
limitations. Change Journals is
another mechanism which we would
consider a medium-weight solution, but
would still have limitations: http://msdn.microsoft.com /en-us/library/aa363798%28VS.85%29.aspx 重量级的解决方案是
写一个专用的文件系统过滤器
位于文件系统中的驱动程序
堆栈并监视文件系统
变化.当然,这将是
最复杂的方法.大多数病毒
扫描仪,备份软件和文件
系统监控实用程序,例如
filemon(www.sysinternals.com)
实施过滤器驱动程序. Heavy-weight solutions would be to
write a dedicated file system filter
driver that sits in the file system
stack and monitors file system
changes. Of course this would be the
most complex approach. Most virus
scanners, backup software, and file
system monitoring utilities such as
filemon (www.sysinternals.com)
implement a filter driver. 希望以上说明对您有所帮助
了解问题的根本原因
您正在体验.请回覆
让我们知道您是否需要
更多信息.谢谢. I hope above explanation helps you to
understand the root cause of the issue
you're experiencing. Please reply to
let us know whether or not you need
further information. Thank you. 这篇关于FileSystemWatcher和Windows 7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
FileSystemWatcher
类使用Windows API函数 ReadDirectoryChangesW
在下面有此限制:FileSystemWatcher
class is using the Windows API function ReadDirectoryChangesW
underneath which has this limit:
当缓冲区长度大于64 KB并且应用程序正在监视网络上的目录时,