21

互联网上有很多关于 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 函数而不必每次都刷新音量?如果用户不是管理员,则不允许这样做,并且还可能需要一些时间才能完成。

4

3 回答 3

1

如果 API 不可靠,那么解决方法可能是您唯一的选择。这当然可能涉及跟踪 lastmodified 和文件名。 这并不意味着您需要在查找更改时进行轮询,而是可以使用 FileSystemWatcher 作为触发检查的手段。

因此,如果您跟踪 ReadDirectoryChangesW /FSW事件发生的最后 50-100 次,并且您看到它被快速调用,您可以检测到这一点并触发特殊条件以获取所有已更改的文件(并设置一个标志,以暂时防止未来的虚假 FSW 事件)在几秒钟内。

由于有些人对此解决方案的评论感到困惑,我建议您应该监控事件从 ReadDirectoryChangesW 到达的速度,以及当它们到达速度过快时,尝试尝试解决方法(通常是手动扫描目录)。

于 2008-09-11T18:34:39.680 回答
1

我们从未见过 ReadDirectoryChangesW 是 100% 可靠的。但是,最好的处理方式是将“报告”与“处理”分开。

我的实现有一个只有一项工作的线程,用于重新排队所有事件。然后是第二个线程来处理我的中间队列。基本上,您希望尽可能少地阻止事件报告。

在 CPU 较高的情况下,您还可以阻止观察者事件的报告。

于 2013-10-01T15:13:10.073 回答
0

我遇到了同样的问题。但是,我没有找到保证获得所有事件的解决方案。在几次测试中,我知道在 GetQueuedCompletionStatus 函数返回后,应该尽快再次调用 ReadDirectoryChangesW 函数。我想如果文件系统的处理速度比我的应用程序处理速度快得多,应用程序可能会丢失一些事件。

无论如何,我将解析逻辑与监控逻辑分开,并将解析逻辑放在一个线程上。

于 2012-05-24T08:17:22.483 回答