一位朋友问我这个问题 - 我认为这是一个很好的问题所以我在这里重新发布它和我的答案:
我有这两个流:
var slowSource = Observable.Interval(TimeSpan.FromSeconds(1));
var fastSource = Observable.Interval(TimeSpan.FromMilliseconds(100));
我希望将它们组合在一起,以便生成包含的输出对 - slowSource的下一个值 - 来自fastSource的最新值
我只需要来自slowSource的每个值一个输出对。例如,前三个输出值可能如下所示:
0,8
1,18,
2,28
一个连接让我接近,但我最终得到每个slowSource多个输出(由于持续时间重叠的方式,我猜):
var qry = slowSource.Join(
right: fastSource,
leftDurationSelector: i => fastSource,
rightDurationSelector: j => fastSource,
resultSelector: (l, r) => {return new {L = l, R = r};})
.Subscribe(Console.WriteLine);
使用GroupJoin和Select生成看起来正确的输出:
var qry2 = slowSource.GroupJoin(
right: fastSource,
leftDurationSelector: i => fastSource,
rightDurationSelector: j => fastSource,
resultSelector: (l, r) => {return new {L= l, R = r};}
)
.Select(async item => {
return new {L = item.L, R = await item.R.FirstAsync()};})
.Subscribe(Console.WriteLine);
然而,这并不是一种很好的方法;必须有一种更好的方法,使用其他组合器以更简单的方式做这样的事情。有吗?
答案 0 :(得分:3)
Zip的重载如何将IObservable
与IEnumerable
结合起来。它使用MostRecent()来获取流的最新值的样本作为可枚举。
slowSource.Zip(fastSource.MostRecent(0), (l,r) => new {l,r})
答案 1 :(得分:1)
Observable.CombineLatest http://msdn.microsoft.com/en-us/library/hh211991(v=vs.103).aspx可以提供帮助,然后您需要以slowSource的速率重新采样fastSource。
var combinedObservable = slowSource.CombineLatest
( fastSource.Sample(slowSource)
, (s,f)=>new {s,f}
);