C# 如何将缓慢移动的可观测值与快速移动的可观测值的最新值相结合

C# 如何将缓慢移动的可观测值与快速移动的可观测值的最新值相结合,c#,system.reactive,C#,System.reactive,一位朋友问我这个问题——我认为这是一个很好的问题,所以我将它和我的答案转发到这里: 我有两条溪流: var slowSource = Observable.Interval(TimeSpan.FromSeconds(1)); var fastSource = Observable.Interval(TimeSpan.FromMilliseconds(100)); 我想把它们结合起来,这样我就能产生包含 -slowSource的下一个值 -来自fastSource的最新值 我只希望slowSou

一位朋友问我这个问题——我认为这是一个很好的问题,所以我将它和我的答案转发到这里:

我有两条溪流:

var slowSource = Observable.Interval(TimeSpan.FromSeconds(1));
var fastSource = Observable.Interval(TimeSpan.FromMilliseconds(100));
我想把它们结合起来,这样我就能产生包含 -slowSource的下一个值 -来自fastSource的最新值

我只希望slowSource的每个值有一个输出对。例如,前三个输出值可能如下所示:

0,8
1,18,
2,28
一个连接让我很接近,但我最终得到了每个slowSource不止一个输出(我想这是由于持续时间重叠的原因):

.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);

然而,这并不是一个很好的方法;必须有一种更好的方法,使用其他组合子以一种更简单的方式来做这样的事情。有吗?

这个将
IObservable
IEnumerable
组合在一起的Zip过载怎么样。它使用MostRecent()获取流的最新值的样本作为可枚举项

slowSource.Zip(fastSource.MostRecent(0), (l,r) => new {l,r})

这个将
IObservable
IEnumerable
组合在一起的Zip重载怎么样。它使用MostRecent()获取流的最新值的样本作为可枚举项

slowSource.Zip(fastSource.MostRecent(0), (l,r) => new {l,r})
Observable.CombineTest可以提供帮助,然后您需要以slowSource的速率对fastSource重新采样

var combinedObservable = slowSource.CombineLatest
    ( fastSource.Sample(slowSource)
    , (s,f)=>new {s,f}
    );
Observable.CombineTest可以提供帮助,然后您需要以slowSource的速率对fastSource重新采样

var combinedObservable = slowSource.CombineLatest
    ( fastSource.Sample(slowSource)
    , (s,f)=>new {s,f}
    );

我考虑过这种方法,但选择了Zip,因为它避免了对slowSource的双重订阅。这种方式对我来说当然有一种更为惯用的感觉。但是,这里有一个bug:在
fastSource
的第一个事件之前传播的任何
slowSource
事件都会丢失。(在我的回答中,
MostRecent
的参数的目的是定义在这个例子中发送什么)给定规范,我不确定它是否是一个bug。如果您希望从快速源获取“最近的”,并且快速源没有任何事件,那么怎么办?在您描述的情况下,您的解决方案会返回什么?在slowSource早于fastSource的情况下,它是否会为“r”返回空值?我正在执行“我只希望slowSource的每个值有一个输出对”的要求。MostRecent允许您指定“null”值。虽然“only”让事情有一点可以解释,但在我看来,慢源事件不应该被忽略。一个
StartsWith()
就足以在必要时对其进行调整。我考虑过这种方法,但选择了Zip,因为它避免了对slowSource的双重订阅。这种方式对我来说当然有一种更为惯用的感觉。但是,这里有一个bug:在
fastSource
的第一个事件之前传播的任何
slowSource
事件都会丢失。(在我的回答中,
MostRecent
的参数的目的是定义在这个例子中发送什么)给定规范,我不确定它是否是一个bug。如果您希望从快速源获取“最近的”,并且快速源没有任何事件,那么怎么办?在您描述的情况下,您的解决方案会返回什么?在slowSource早于fastSource的情况下,它是否会为“r”返回空值?我正在执行“我只希望slowSource的每个值有一个输出对”的要求。MostRecent允许您指定“null”值。虽然“only”让事情有一点可以解释,但在我看来,慢源事件不应该被忽略。如果需要,一个
StartsWith()
就足以对其进行调整。