在CombineLatest中确定并操作最新更新的序列

时间:2015-08-21 00:44:47

标签: c# system.reactive

我想知道是否有现有的运算符或某个逻辑允许我重现具有2个源序列的CombineLatest的行为,但是增加了确定修改了2个序列中哪个序列的能力持续。反过来,我希望在组合两个序列的最新结果时使用这种区别来改变我的操作方式。

我认为表达我想要的东西的一个好方法是给出一个方法签名的例子来实现我所说的逻辑。

public static IObservable<TResult> MyOperator<TInLeft, TInRight, TResult>(
    this IObservable<TInLeft> left, 
    this IObservable<TInRight> right, 
    Func<TInLeft, TInRight, bool, TResult> selector)
{
    // ...magic 
} 

在这种情况下,leftright将是条目序列,传递给方法的selector func将其布尔参数值设置为true以指示left序列是最近更改的来源,false如果是最后更改的right序列。

当然,为了清楚起见,该方法也可以通过以下方式重新制定

public IObservable<TResult> MyOperator<TInLeft, TInRight, TResult>(
    this IObservable<TInLeft> left, 
    this IObservable<TInRight> right, 
    Func<TInLeft, TInRight, TResult> whenLeft,
    Func<TInLeft, TInRight, TResult> whenRight)
{
    // ... more magic
} 

其中,不是使用布尔来区分最近更新的序列,而是每个序列都以func的形式包含其自己的行为。

此类运算符的用例是我希望共享结果取决于leftright序列的某种组合(就像CombineLatest),但是优先权取决于最新信息。我希望我的意图足够明白。

是否存在具有类似基础逻辑或可以适应此目的的现有运营商?我怎么能完成这样的行为呢?我对一些可能有用的运算符有一个模糊的概念,但似乎可能有很多不同的方法,我只是不确定实现我想要的最佳方法。

2 个答案:

答案 0 :(得分:3)

这就是我要做的事情:

var combined =
    source1.Timestamp()
        .CombineLatest(source2.Timestamp(), (ts1, ts2) => new { ts1, ts2 });

combined.Select(x =>
    x.ts1.Timestamp < x.ts2.Timestamp
        ? "source1 first"
        : "source2 first");

答案 1 :(得分:2)

您可以尝试将Timestamp运算符与CombineLatest结合使用。像这样:

    var obs1 = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp();
    var obs2 = Observable.Interval(TimeSpan.FromSeconds(2)).Timestamp();

    var result = Observable.CombineLatest(obs1, obs2, (v1, v2) =>
    {
        if(v1.Timestamp < v2.Timestamp)
        {
            Console.WriteLine("v1 " + v1.Timestamp);
            return v1;
        }
        else
        {
            Console.WriteLine("v2 " + v1.Timestamp);
            return v2;
        }       
    });

    result.Subscribe(x => Console.WriteLine(x));