C# 可观察到定期处理目录中的文件
我试图生成一系列事件,这些事件由目录中现有文件的文件名组成 这很有效。代码如下所示:C# 可观察到定期处理目录中的文件,c#,system.reactive,C#,System.reactive,我试图生成一系列事件,这些事件由目录中现有文件的文件名组成 这很有效。代码如下所示: Observable.Generate( ExistingFiles(path, filter), Condition(), Iterate(), CreateFileChangedEvent()
Observable.Generate(
ExistingFiles(path, filter),
Condition(),
Iterate(),
CreateFileChangedEvent()
)
private static Func<List<string>.Enumerator, FileChangedEvent> CreateFileChangedEvent()
{
return enumerator => new FileChangedEvent(enumerator.Current, @"Existing");
}
private static Func<List<string>.Enumerator, List<string>.Enumerator> Iterate()
{
return enumerator =>
{
enumerator.MoveNext();
return enumerator;
};
}
private static List<string>.Enumerator ExistingFiles(string path, string filter)
{
List<string>.Enumerator files =
Directory.GetFiles(path, filter)
.ToList()
.GetEnumerator();
// Advance the enumerator to the first result
files.MoveNext();
return files;
}
private static Func<List<string>.Enumerator, bool> Condition()
{
return enumerator => enumerator.Current != null;
}
}
如果要在计算机上运行文件搜索,可以执行以下操作:
Observable.Interval(TimeSpan.FromSeconds(2))
.Select(_ =>
Directory.GetFiles(path, filter)
.ToObservable()
.Select(s => new FileChangedEvent(s, @"Existing"))
)
.SelectMany(_ => _)
.Subscribe(onNewFileChangedEvent => {
Console.WriteLine(onNewFileChangedEvent.ToString());
});
但这将产生相同的“现有”文件更改事件,我想在将它们发送到订阅之前,您需要消除重复?。您可以使用创建两组文件的差异,并仅发射这些文件
为什么选择了很多
原始流从间隔返回计时器事件。在每个事件中,我们都返回一个新的FileChangedEvents流
因为我们想把这些数据融合到一个流中,用户可以使用这些数据流,所以我们必须合并这些结果。输入SelectMany,它将投影和展平合并为一个步骤。因为我们对selectMany的projection属性不感兴趣,所以我们表示,我们不会对带有=>u下划线语法的约定所指示的项执行任何操作
我不能只使用合并操作符吗?
Merge本质上是identity SelectMany的语义等价物。有一些重载可以做一些有趣的事情,比如控制并发。连续生成要合并的序列肯定没有问题。以下是似乎大多数代码都涉及将IEnumerable转换为IObservable。有什么理由不为IEnumerables使用适当的ToObservable扩展方法吗?没有。我将从这个开始。照它的工作原理,并且,正如您所说,为目录中的每个文件发出重复的文件。你能详细介绍一下SelectMany吗?你可以用.Merge代替.SelectMany。\u=>\u我现在用Distinct来过滤已经生成的事件。不再有重复项。@Mark Merge本质上是标识SelectMany的语义等价物。\uMany=>\uMany重载可以执行一些有趣的操作,比如控件并发性。连续生成要合并的序列肯定没有问题。这是最初的实现:@Mark事实上,据我所知,您引用的文档也没有提到任何此类限制-事实上,它明确讨论了使用流作为源…或者甚至是发出可观察的可观察对象。。。
Observable.Interval(TimeSpan.FromSeconds(2))
.Select(_ =>
Directory.GetFiles(path, filter)
.ToObservable()
.Select(s => new FileChangedEvent(s, @"Existing"))
)
.SelectMany(_ => _)
.Subscribe(onNewFileChangedEvent => {
Console.WriteLine(onNewFileChangedEvent.ToString());
});
t1--t2--t3
\ \ \
\ \ ---t3{evt1,evt2,evt3}
\ ---t{evt1,evt2,evt3}
---t1{evt1,evt2,evt3}