草庐IT

c# - FileSystemWatcher 和 windows 7

coder 2024-05-24 原文

我正在编写一个监视网络目录的工具并在 Windows Server 2008 机器上运行,FileSystemWatcher 的 OnChanged 事件被任何未使用 Windows 7 的计算机放置在网络驱动器上的文件正确触发,出于某种原因,如果在 Windows 7 计算机上(一次)复制的文件数量超过 19 个,则不会触发任何事件,尽管如果文件是单独完成的,它会起作用。是否有解决此问题的方法,或者 Windows 7 内核如何处理 FSW 事件?

澄清一下,当从 XP 机器复制时,它适用于数以千计的文件。 (该软件仍在2008服务器机器上)。

最佳答案

来自 MSDN :

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.

如果增加缓冲区大小还不够,并且您无法控制一次触发事件的文件数,则必须添加额外的轮询。

另请参阅此相关问题:

FileSystemWatcher does not work properly when many files are added to the directory at the same time…

更新:

简单地增加缓冲区大小可能很诱人,但这应该小心完成。事实上,在网络访问方面有 64k 的限制。 FileSystemWatcher 类正在使用 Windows API 函数 ReadDirectoryChangesW下面有这个限制:

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 的帖子:

FileSystemWatcher across the network (full post quoted below)

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 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.

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.

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.

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.

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

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.

关于c# - FileSystemWatcher 和 windows 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3250343/

有关c# - FileSystemWatcher 和 windows 7的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  8. ruby - 如何在 Ruby 中执行 Windows CLI 命令? - 2

    我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解

  9. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

  10. ruby - 可以像在 C# 中使用#region 一样在 Ruby 中使用 begin/end 吗? - 2

    我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用

随机推荐