c# - 在响应式扩展中包装一个文件观察器

标签 c# system.reactive

我一直在考虑将文件观察器包装在可观察对象中以帮助处理事件,但我在弄清楚如何从中获得我想要的行为时遇到了一些麻烦。文件监视程序监视放置文件的目录。当文件首次放入该目录时,将在文件观察器上触发 Created 事件。但是,如果文件很大或网络连接速度较慢,则会在文件更新时触发一系列 Changed 事件。我不想在文件完成写入之前处理文件,所以我真正需要的是这个时间轴

|Created    |Changed   |Changed   |Changed                      
________________________________________________ 
^Write starts       ^Write finishes       ^Processing Starts    

我看了很多在 Rx 中过滤事件的方法,但我无法得到我需要的东西,即“一旦文件文件在 X 秒内没有被更改就触发一个函数”。 throttle 不好,因为它会在中间丢失事件。缓冲区不好,因为事件可能发生在缓冲区边界上。

我曾考虑过使用超时,但我并不认为他们会抛出异常,我希望处理在文件写入时开始,而不是在没有更多事件发生时开始。

Reactive Extensions vs FileSystemWatcher 也有类似的问题这从未真正解决过。

有没有一种方法可以让我轻松做到这一点?我相信这不是一个罕见的用例。

最佳答案

ObservableFileSystemWatcher - FileSystemWatcher type 的可观察包装器- 工作完美。添加名为 ReactiveFileSystemWatcher 的 NuGet 包,并创建控制台应用程序进行如下测试

class Program
{
  static void Main(string[] args)
  {
    using (var watcher = new ObservableFileSystemWatcher(c => { c.Path = @"C:\FolderToWatch\"; c.IncludeSubdirectories = true; }))
    {
      watcher.Created.Select(x => $"{x.Name} was {x.ChangeType}").Subscribe(Console.WriteLine);
      watcher.Changed.Select(x => $"{x.Name} was {x.ChangeType}").Subscribe(Console.WriteLine);
      watcher.Renamed.Select(x => $"{x.OldName} was {x.ChangeType} to {x.Name}").Subscribe(Console.WriteLine);
      watcher.Deleted.Select(x => $"{x.Name} was {x.ChangeType}").Subscribe(Console.WriteLine);
      watcher.Errors.Subscribe(Console.WriteLine);
      watcher.Start();
      Console.ReadLine();
    }
  }
}

关于c# - 在响应式扩展中包装一个文件观察器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14159021/

相关文章:

c# - 用于 silverlight 4 + WCF 数据服务的 IAsyncRepository 或 IObservableRepository

c# - Reactive Extensions : Split input, 进程,并连接回来

c# - .PublishLast()(以前称为 Prune)的用例

c# - Linq to Entities - 使用 Include() 进行预加载

c# - 使用 xmldocument 读取 xml

C# 不能使用 **as** 将基类转换为派生类

c# - 用户确认的异步命令执行

c# - Rx.NET "gate"运算符

c# - 从代码后面将变量传递给 javascript 函数

c# - 如何从配置文件禁用 Entity Framework 中的缓存