C# – 预测文件夹删除时的文件系统事件

这是一个关于实现这一目标的最佳实践的问题。

我有一个FileSystemWatcher ,它应该告诉我用户对文件和文件夹的更改。 还观察了细分市场。 在同一目录中,我的程序有时也会发生变化。 我不希望FileSystemWatcher检测这些程序更改的事件。

我的第一个实现是一个列表,我可以添加预期的事件。 当我收到文件系统事件时,我检查列表并忽略它,如果它在那里。 这听起来不太健壮,但似乎有效。

现在我发现了真正的问题:
D:由FileSystemWatcher监视。
我有两个这样的文件夹:D:\ folder1 \ folder2
现在我想用我的应用程序删除folder1(其中包含folder2)。 所以我把D:\ folder1放在我的删除列表中。 然后我调用Directory.Delete(@"D:\folder1", true) 。 现在我注意到在exception中无法删除folder1(为什么有)。 我从列表中删除了删除条目,但是folder2已经被删除了,我得到了他的FileSystemEvent。 所以我得到了D:\ folder1 \ folder2的FileSystem事件。 我的程序现在认为用户已经删除了这个文件夹并且做错了。

我现在有一些想法:

1.)通过删除每个文件和每个文件夹来递归删除文件夹。 有了这个,我得到每个子文件夹并提交一个自己的列表条目。 我已经实现了它,但它非常非常慢。

2.)也许有更好的方法在FileSystemWatcher使用聪明的filter使我的列表过时了?

3.)如果可以删除所有内容,也许只能删除目录树。 所以,如果它失败了,我仍然拥有一切,如果不是,一切都被删除。 这对我来说似乎是最优雅的解决方案,但不知道这是否可行?

4.)是否可以通过我的软件专门锁定所有文件和文件夹? 如果这样就可以了,应该可以用一个删除命令删除所有内容,或者像这样删除?

我也愿意接受其他解决方案。

编辑1以使其更清晰:

我只想“看到”文件夹上的用户操作。 如果我在这里操作我的程序中的东西,我不想看到这个事件。

通过我的实现,如果文件夹被锁定且无法删除,我将获取子文件夹的事件。

用英语解释并不容易,因为我不是英语母语者;)。

编辑2:

5.)也许可以在FileSystemWatcher过滤定义过程中的所有事件?

我最近做过这样的事情; 诀窍是让你的’列表’识别出列表中有文件夹名称的位置,如果它期望删除事件,也会丢弃该文件夹中任何事件的任何事件,并且只有当它是文件夹本身时才从预测列表中删除它。

我应该警告你,如果有太多事件快速连续发生,你可能会遇到FileSystemWatcher缓冲区变满的问题; 如果是这样,它将触发Error事件,并且无法通知您一大堆事件。 如果您的预测列表在收到事件时删除了项目,那么您可能会因为缓冲区溢出而无法收到您想要忽略的事件而忽略未来事件。 它也可能变得非常大,因为项目永远不会从列表中删除。

我还没有找到一种可靠的方法,尽管你可以将FileSystemWatcher缓冲区的大小设置为最大,以便在一定程度上缓解它。

编辑:同样非常重要:返回的事件在不同的线程上执行(除非您的处理程序位于实现ISynchronizeInvoke的对象上,例如ControlForm ,并且您将SynchronizingObject设置为您的Control / Form 。这意味着您需要非常小心你如何维护你的列表,考虑到潜在的竞争条件。我仍然在努力解决这个问题;我的代码在收到错误事件时刷新预测列表,但是当它处理事件时,其他更改错误已经被触发和处理的事件,它刷新了不应该的事情。

关于缓冲区溢出。 解决问题的最佳方法是响应另一个线程上的事件来完成工作。 我是这样做的

 // Queue of changed paths. private readonly Queue mEventQueue = new Queue(); // add this as handler for filesystemwatcher events public void FileSystemEvent(object source, FileSystemEventArgs e) { lock (mEventQueue) { if (!mEventQueue.Contains(e.FullPath)) { mEventQueue.Enqueue(e.FullPath); Monitor.Pulse(mEventQueue); } } } // start this on another thread public void WatchLoop() { string path; while (true) { lock (mEventQueue) { while (mEventQueue.Count == 0) Monitor.Wait(mEventQueue); path = mEventQueue.Dequeue(); if (path == null) break; } // do whatever you want to do } } 

这样我就不会错过任何一个活动

好的,这是我解决问题的方法:

只是为了删除命令:

我实现了2个列表,一个用于文件删除,一个用于删除文件夹。

文件列表entrys没有超时。 如果我删除文件,我创建一个列表条目,如果我得到预期的删除事件,我像以前一样删除该条目。

文件夹列表在创建后没有超时。 我可以通过特殊方法手动命令它们在一秒钟之后超时。 如果删除文件夹,我会添加一个deleteFolder列表条目。 由于此删除文件夹条目,将忽略此文件夹或文件或子文件夹或子文件夹文件中的每个删除事件。 删除完成后,我为deleteFolder条目设置了超时。 如果删除抛出exception,我也会这样做。 所以我希望在一秒钟之后得到所有活动。 所以如果删除命令有效,我会忽略所有事件。 在此之后删除deleteFolder列表条目。

限制:1。删除事件发生后,所有删除事件必须在一秒钟内完成。 2.不允许删除这样的文件夹:
删除文件夹(已完成)
再次创建文件夹
等不到1秒
再次删除文件夹(超时尚未完成删除文件夹列表条目)

希望这有助于某人甚至它非常复杂^^