FileSystemWatcher 长期以来一直困扰着我的一件事是它为文件的单个逻辑更改触发多个事件的方式。我知道它为什么会发生,但我不想关心 - 我只想重新解析文件一次,而不是连续 4-6 次。理想情况下,只有在给定文件完成更改时才会触发一个事件,而不是沿途的每一步。
多年来,我为这个问题提出了各种不同程度的丑陋解决方案。我认为 Reactive Extensions 将是最终的解决方案,但有些事情我做得不对,我希望有人能指出我的错误。
我有一个扩展方法:
public static IObservable<IEvent<FileSystemEventArgs>> GetChanged(this FileSystemWatcher that)
{
return Observable.FromEvent<FileSystemEventArgs>(that, "Changed");
}
最终,我想在给定的时间段内为每个文件名获取一个事件 - 这样一来,具有单个文件名的连续四个事件减少为一个事件,但如果同时修改多个文件,我不会丢失任何内容时间。BufferWithTime
听起来像是理想的解决方案。
var bufferedChange = watcher.GetChanged()
.Select(e => e.EventArgs.FullPath)
.BufferWithTime(TimeSpan.FromSeconds(1))
.Where(e => e.Count > 0)
.Select(e => e.Distinct());
当我订阅这个 observable 时,对受监视文件的一次更改会连续四次触发我的订阅方法,这完全违背了目的。如果我删除该Distinct()
调用,我会看到四个调用中的每一个都包含两个相同的事件 - 因此正在进行一些缓冲。增加传递给的 TimeSpanBufferWithTime
似乎没有任何效果 - 我高达 20 秒,但行为没有任何变化。
这是我第一次涉足 Rx,所以我可能遗漏了一些明显的东西。我做错了吗?有更好的方法吗?感谢您的任何建议...