Observable.Buffer是否可能在时间以外的东西上

时间:2012-03-05 13:56:20

标签: c# system.reactive reactive-programming observable

我一直在寻找有关如何在rx中使用Observable.Buffer的示例,但找不到比锅炉板时间缓冲的东西更重要的东西。

指定一个“bufferClosingSelector”似乎有一个重载,但我无法理解它。

我要做的是创建一个按时间或“累积”缓冲的序列。 考虑一个请求流,其中每个请求都有一定的权重,我不希望一次处理超过x累计权重,或者如果累积不够,只需给我最后一个时间帧(常规缓冲区功能) )

1 个答案:

答案 0 :(得分:15)

bufferClosingSelector是一个函数,每次调用一个Observable,当预期缓冲区被关闭时,它会产生一个值。

例如,

source.Buffer(() => Observable.Timer(TimeSpan.FromSeconds(1)))的作用类似于常规Buffer(time)重载。

如果您想对序列进行加权,可以在序列上应用Scan,然后决定您的聚合条件。

例如,source.Scan((a,c) => a + c).SkipWhile(a => a < 100)为您提供一个序列,当源序列加起来超过100时,该序列会产生一个值。

您可以使用Amb来竞争这两个结束条件,看看哪个首先做出反应:

        .Buffer(() => Observable.Amb
                     (
                          Observable.Timer(TimeSpan.FromSeconds(1)), 
                          source.Scan((a,c) => a + c).SkipWhile(a => a < 100)
                     )
               )

您可以使用任何一系列组合器,它们可以为缓冲区产生任何值。

注意: 给关闭选择器的值无关紧要 - 这是重要的通知。因此,要将不同类型的来源与Amb合并,只需将其更改为System.Reactive.Unit即可。

Observable.Amb(stream1.Select(_ => new Unit()), stream2.Select(_ => new Unit())