我正在学习RX,并且在我对Rx网站的介绍上遇到了一个问题。下面是一个实现与带有计数扩展方法的Window相同功能的示例:
public static IObservable<IObservable<T>> MyWindow<T>(
this IObservable<T> source,
int count)
{
var shared = source.Publish().RefCount();
var windowEdge = shared
.Select((i, idx) => idx % count)
.Where(mod => mod == 0)
.Publish()
.RefCount();
return shared.Window(windowEdge, _ => windowEdge);
}
我理解var shared = source.Publish().RefCount()
行的目的是分享&#39;具有窗口边缘查询的源。我不明白为什么windowEdge
查询也是用.Publish().RefCount()
定义的?有人可以帮我理解为什么这是必要的吗?
答案 0 :(得分:2)
好问题!
除性能原因外,重新计算windowEdge的原因与Select
的使用有关。
在此示例中,Select
正在使用索引参数(idx
),其值是针对每个新订户唯一确定的。因此,如果我们没有重新计算windowEdge
,则每个新订阅者都会在下一个项目产生时收到一个事件,因为mod == 0
将始终为真。
这意味着没有重新计数,每个窗口将由两个值组成(假设没有引入其他竞争条件)。例如:
当第一个事件触发时,我们创建一个新窗口并在事件中输入,此时我们还使用窗口关闭选择器来获得一个observable,它将在窗口关闭时产生。将触发下一个事件,并将其发送到当前窗口。该事件也恰好是发送到我们的窗口关闭observable的第一个事件(因为mod == 0
始终为true)。窗口关闭的observable现在已经触发,窗口关闭,给我们留下了一个包含两个元素的窗口。重复。
使用windowEdge
的ref-count是必要的,以确保每个“MyWindow”可观察时只增加idx
次。