【问题标题】:FileSystemWatcher pitfallsFileSystemWatcher 的陷阱
【发布时间】:2017-11-21 01:06:36
【问题描述】:

我正在开发一个需要使用 FileSystemWatcher 类的 C# 程序,以便在创建新文件时通知它。作为初始化的一部分,程序会扫描目录,以便处理其中已存在的任何文件。这一切都很好。

但是,在与另一位开发人员的讨论中,我们开始质疑这是否总是有效。是否存在FileSystemWatcher 会错过创建文件的条件?如果有,这些条件是什么?

为了处理这种情况,我们只需在初始化过程中运行定期扫描目录的代码,但FileSystemWatcher 丢失文件的可能性有多大?

【问题讨论】:

标签: c# filesystemwatcher


【解决方案1】:

FileSystemWatcher 不会通常丢失文件。然而:

  • 由于它基于ReadDirectoryChangesW,它只检测文件目录条目的更改,而不检测文件本身的更改。对文件的大多数更改都会更新目录条目,但也有少数例外(请参阅this article)。
  • 文件更改通知的缓冲区大小有限;如果您处理事件的速度不够快,缓冲区将溢出,导致您错过事件。这就是为什么您不应该在事件处理程序中进行任何繁重的处理;如果您不能足够快地处理事件,只需将它们添加到您在另一个线程上处理的队列中。

其他陷阱:

  • 通知不会立即到达;实际更改和通知之间的延迟通常很短,但我已经看到它长达几秒钟。对于大多数用例来说,这不是主要问题,但根据您要执行的操作,这可能是个问题。
  • Moved 没有事件。如果您将文件从一个目录移动到另一个目录,您将收到两个通知:DeletedCreated
  • 有时,根据音量配置,通知中的路径可能是旧的 8.3 格式(例如,您可以获得 SOMETH~1.TXT 而不是 Something.txt
  • 如果您将现有的非空目录移动到监视目录中,您只会收到有关目录本身的通知,而不是其内容。您需要手动检查内容。
  • Changed 事件可以针对同一个文件发生多次;您需要自己处理重复项

【讨论】:

  • 感谢您的详细回复。我们已经知道多个 Changed 事件和 Move 陷阱。我今天早些时候读过关于移动非空目录的问题。我不知道目录条目与文件本身的问题。幸运的是,我只对添加的新文件感兴趣,而不是对现有文件的更改。再次感谢!
【解决方案2】:

FileSystemWatcher 不应该错过任何文件,但是,如果您的文件处理时间很长,您应该将事件排队并在不同的线程中处理它们。

【讨论】:

    【解决方案3】:

    我不时使用 fs watcher,最大的挑战总是 FSwatcher 在文件创建时创建事件触发器(实际上没有最终大小),这意味着如果有人在文件中插入一个巨大的文件“演出”将被锁定,直到创建者应用程序发布文件,所以我可以在测试环境中看到完美,有限的文件和数据可以出现。对于生产 fswatcher 结合后台工作人员和计时器可以是解决方案,例如创建的 FSwatcher 甚至应该将任务移交给后台工作人员。我仍然看到一些情况,我需要每小时计时器来移动剩余的文件,当用户在几个小时内仍在使用文件时,有一些奇怪的情况。我发现完美的解决方案是使用 FSwatcher 以及多线程和计时器。我假设您想要一个 Windows 服务,而不是基于表单或基于 Web 的应用程序。对于文件更改事件,我不会使用它,如果任何应用程序在文件流中打开文件,它将执行几个更改,但仍会锁定文件,所以你不能对它做任何事情,也许你可以添加到列表中以便能够稍后再处理它,但据我所知,在这种情况下,如果文件是在流中编辑的,它将继续触发你的事件。所以我的建议使用创建的事件在事件中设置一些超时来检查真正快速的读取可用性,比如 5 秒,如果没有发生这种情况,则生成一个后台线程,甚至 bg 线程仍然无法处理文件,有一个计时器可以不断重试在所有文件上,这两种情况都没有处理(比如大文件和服务终止,然后你的后台线程被释放)。

    总结 FSwatcher 引发事件,但这并不意味着文件可以访问并准备好进行处理,它只是监视文件系统并触发您订阅的事件。事件触发,但如果你处理得不够快,你可能会错过下一个,所以使用 event 进行非常快速的操作,如果你创建了很多文件,比如将它们添加到列表中,以及一个单独的威胁要做任务!如果你在一个活动上花费太多时间,你可能会错过一些,所以抓住这个活动,立即交接任务,等待下一个:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 2011-10-07
      相关资源
      最近更新 更多