C#:使用FileSystemWatcher监视文件的更改

C#:使用FileSystemWatcher监视文件的更改,c#,io,filesystemwatcher,C#,Io,Filesystemwatcher,好的,所以我从中学到了我应该使用a来监视文件的更改。现在的问题是,如果我必须跟踪许多文件,我是否为每个文件创建一个观察者?此外,一旦文件关闭,我必须以某种方式处置观察者。使用字典存储文件路径和文件系统监视程序是一种可行的方法吗?当我打开更多的文件时,我会添加更多的观察者,当我关闭时,会适当地处理观察者。有太多的观察者会是一件坏事吗 更新 我就这么做了 protected void AttachFileMonitor(EditorTabViewModel tab) { string fil

好的,所以我从中学到了我应该使用a来监视文件的更改。现在的问题是,如果我必须跟踪许多文件,我是否为每个文件创建一个观察者?此外,一旦文件关闭,我必须以某种方式处置观察者。使用
字典
存储文件路径和
文件系统监视程序
是一种可行的方法吗?当我打开更多的文件时,我会添加更多的观察者,当我关闭时,会适当地处理观察者。有太多的观察者会是一件坏事吗

更新

我就这么做了

protected void AttachFileMonitor(EditorTabViewModel tab)
{
    string file = tab.FilePath;
    if (!_fsWatchers.ContainsKey(file))
    {
        var watcher = new FileSystemWatcher();
        watcher.Path = Path.GetDirectoryName(file);
        watcher.Filter = Path.GetFileName(file);
        watcher.Changed += (s, e) =>
        {
            string message = "";
            string caption = "";
            MessageBoxButton buttons = MessageBoxButton.YesNo;
            MessageBoxImage image = MessageBoxImage.Question;
            MessageBoxResult defaultResult = MessageBoxResult.Yes;
            MessageBoxResult result = _dialogSvc.GetMessageBox(message, caption, buttons, image, defaultResult);
            if (result == MessageBoxResult.Yes)
            {
                tab.Open(file);
            }
        };
        _fsWatchers.Add(file, watcher);
    }
}
protected void DetachFileMonitor(EditorTabViewModel tab)
{
    if (_fsWatchers.ContainsKey(tab.FilePath)) {
        _fsWatchers.Remove(tab.FilePath);
    }
}

我发现
Changed()
从未被触发

如果您为每个目录创建一个观察者就足够了(或者,您可以让观察者监视整个目录树)。然后您可以使用事件将更改的文件与感兴趣的文件列表进行比较

我建议您为观察者创建某种类型的“保姆”类,以确保您不会处理活动的观察者,或创建重复的观察者。只是一个提示:)


顺便说一句,是的,有一个限制,你不能创造无限的观察者。在特定的情况下,这可能会成为一个问题,但最有可能的是,你不是这样的

我认为你肯定走对了方向。如何存储多个FileWatcher取决于您,但是尽快处理它们并清除它们的队列对于可靠性非常重要。每个目录只需要一个,而不是文件


有很多关于FileWatcher不可靠的帖子,所以在使用时要勤勉。

这确实是一种折衷。许多观察者将消耗更多的资源,但如果您在包含许多文件/子目录(例如C:)的目录上有一个观察者,这也将消耗大量资源


如果所有文件都位于一个文件夹中,您应该只使用一个观察者。

还有一件事需要考虑:观察者会消耗资源,是的,但它不会轮询,而且轮询在大多数情况下是有害的。最好是无所事事地等待,而不是主动要求。就性能和响应能力而言,显然更倾向于等待而不是询问。不,这不是轮询。但是,它将接收您指定的文件夹结构中的所有更改。特别是当您指定C:\时,您将收到C:\驱动器上所有活动的通知,这将非常多。是的,我知道这不会是轮询,我正在谈论使用FileSystemWatcher的替代方法:轮询;)但如果您指定C:\将不会有太多活动,除非您启用递归模式。我想说的一点是,投票很可能比观察者使用更多的资源。我想知道我是否做错了什么
FileSystemWatcher
似乎不适合我。或者这就是为什么这么多人警告不要使用它?我猜,但您是否已将EnableRaisingEvents设置为true?这很有效,但即使在我从应用程序保存时,更改也会被提升2次。我了解到可能会发生这种情况,但如何检查事件是否已引发b4?这听起来有点奇怪,但一个简单的解决方案是获取文件的LastWriteTime,保存它,然后在eventhandler中进行比较。如果改变:问,如果没有改变:不知道我是否做错了什么
FileSystemWatcher
似乎不适合我。或者这就是为什么这么多人警告不要使用它?将EnableRaisingEvents设置为true:)