反应性扩展vs FileSystemWatcher [英] Reactive Extensions vs FileSystemWatcher

查看:80
本文介绍了反应性扩展vs FileSystemWatcher的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

长期困扰我关于FileSystemWatcher的一件事是它为文件的单个逻辑更改触发多个事件的方式。我知道为什么会发生这种情况,但我不必担心-我只想将文件重新解析一次,而不是连续4-6次。理想情况下,只会发生一个事件,该事件仅在给定文件完成更改时才会触发,而不是整个过程中的每一步。

One of the things that has long bugged me about the FileSystemWatcher is the way it fires multiple events for a single logical change to a file. I know why it happens, but I don't want to have to care - I just want to reparse the file once, not 4-6 times in a row. Ideally, there would be an event that only fires when a given file is done changing, rather than every step along the way.

针对这个问题的各种解决方案,程度不同。我以为Reactive Extensions将是最终的解决方案,但是有些事情我做得不对,我希望有人指出我的错误。

Over the years I've come up with various solutions to this problem, of varying degrees of ugliness. I thought Reactive Extensions would be the ultimate solution, but there's something I'm not doing right, and I'm hoping someone can point out my mistake.

我有一个扩展方法:

public static IObservable<IEvent<FileSystemEventArgs>> GetChanged(this FileSystemWatcher that)
{
    return Observable.FromEvent<FileSystemEventArgs>(that, "Changed");
}

最终,我想在给定时间内为每个文件名获取一个事件期间-这样一来,将具有单个文件名的连续四个事件减少为一个事件,但是如果同时修改多个文件,我不会丢失任何内容。 BufferWithTime 听起来是理想的解决方案。

Ultimately, I would like to get one event per filename, within a given time period - so that four events in a row with a single filename are reduced to one event, but I don't lose anything if multiple files are modified at the same time. BufferWithTime sounds like the ideal solution.

var bufferedChange = watcher.GetChanged()
    .Select(e => e.EventArgs.FullPath)
    .BufferWithTime(TimeSpan.FromSeconds(1))
    .Where(e => e.Count > 0)
    .Select(e => e.Distinct());

当我订阅此可观察对象时,对受监视文件的单个更改会在四次触发我的订阅方法连续,这很不利于目标。如果删除 Distinct()调用,我会看到四个调用中的每个都包含两个相同的事件-因此存在一些缓冲。增加传递给 BufferWithTime 的TimeSpan似乎没有任何效果-我的行为持续了20秒之久。

When I subscribe to this observable, a single change to a monitored file triggers my subscription method four times in a row, which rather defeats the purpose. If I remove the Distinct() call, I see that each of the four calls contains two identical events - so there is some buffering going on. Increasing the TimeSpan passed to BufferWithTime seems to have no effect - I went as high as 20 seconds without any change in behavior.

这是我第一次尝试Rx,所以我可能缺少明显的东西。我做错了吗?有没有更好的方法?感谢您的任何建议...

This is my first foray into Rx, so I'm probably missing something obvious. Am I doing it wrong? Is there a better approach? Thanks for any suggestions...

推荐答案

我的错误。不知何故,我有多个FileSystemWatchers监视彼此的文件夹。可观察对象为每个观察者触发一次,但 BufferWithTime 似乎正常工作。我仍然需要弄清楚为什么我的观察者会触发我认为配置为忽略的文件夹事件,但这与Rx或此问题无关。

My mistake. Somehow I've got multiple FileSystemWatchers monitoring each other's folders. The observable was triggering once for each watcher, but BufferWithTime appears to be working correctly. I still need to figure out why my watchers are firing events for folders I thought they were configured to ignore, but that's got nothing to do with Rx or this question.

在实际上,也许我可以解决这个问题,然后切换到让单个观察者监视父文件夹,使用Rx从我不感兴趣的文件夹中过滤出事件。

In fact, maybe I can punt on that problem, and switch to having a single watcher monitoring a parent folder, using Rx to filter out events from folders I'm not interested in.

这篇关于反应性扩展vs FileSystemWatcher的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆