互联网上有很多关于ReadDirectoryChangesW API函数在有大量文件活动时丢失文件的帖子。大多数人都指责调用ReadDirectoryChangesW函数循环的速度。这是一个不正确的假设。我见过的最好的解释是在下面的帖子,评论于2008年4月14日星期一下午2:15:27
http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/
摘要是ReadDirectoryChangesW函数报告文件更改,因为它们离开文件后写队列,而不是添加它们。如果在提交之前添加了太多,则会忽略其中一些。如果您只是编写一个程序来快速生成目录中的1000多个文件,您可以通过实现看到这一点。只要计算一下您收到的文件事件通知数量,您就会看到有时候您不会收到所有这些通知。
问题是,有没有人找到一种可靠的方法来使用ReadDirectoryChangesW函数而不必每次都刷新音量?如果用户不是管理员并且也可能需要一些时间来完成,则不允许这样做。
答案 0 :(得分:1)
如果API不可靠,那么解决方法可能是您唯一的选择。这当然可能涉及跟踪lastmodified和filenames。 这并不意味着您需要在查找更改时进行轮询,而是可以使用FileSystemWatcher作为触发检查的方法。
因此,如果您跟踪ReadDirectoryChangesW / FSW 事件发生的最后50-100次,并且您看到它被快速调用,您可以检测到这一点并触发特殊条件以获取几秒钟内所有已更改的文件(并设置一个标志以防止未来的伪造FSW事件)。
由于有些人对此解决方案的评论感到困惑,我建议您应该监控事件从ReadDirectoryChangesW到达的速度,以及当它们到达太快时,尝试尝试解决方法(通常是手动扫描目录)。
答案 1 :(得分:1)
我们从未见过ReadDirectoryChangesW 100%可靠。但是,处理它的最佳方法是将“报告”与“处理”分开。
我的实现有一个只有一个作业的线程,可以重新排队所有事件。然后是第二个线程来处理我的中间队列。基本上,您希望尽可能少地阻止事件报告。
在高CPU情况下,您还可以阻止观察者事件的报告。
答案 2 :(得分:0)
我遇到了同样的问题。但是,我没有找到能够保证获得所有活动的解决方案。在几个测试中,我可以知道在GetQueuedCompletionStatus函数返回后应该尽快再次调用ReadDirectoryChangesW函数。我想如果文件系统的处理速度比我的应用程序处理速度快得多,那么应用程序可能会丢失一些事件。
无论如何,我将一个解析逻辑与监控逻辑分开,并在一个线程上放置一个解析逻辑。