有条件地组合两个Rx流

时间:2016-02-12 11:26:35

标签: c# stream task-parallel-library system.reactive reactive-programming

我正在尝试使用Rx实现一个场景,我有两个热门的Observable。流1和流2.基于流1的数据,我需要启动流2或停止流2.然后使用CombineLatest将流数据合并为一个。下面是我能够提出的代码。

  1. 有没有更好的方法来实现这个?

  2. 我怎样才能使它更通用,就像我将拥有流1然后流2 .. n来自2的每个流... n有条件条件2 .. n利用流1的数据来检查是否需要启动其他流,然后以CombineLatest方式组合所有数据

  3. CODE:

            IDisposable TfsDisposable = null;
    
            // stream 1
            var hotObs = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1));
    
    
            // stream 2
            var hotObs2 = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1)).Publish();
    
    
            var observerHot =  hotObs.Do(a => 
            {
                // Based on Condition to start the second stream
                if (ConditionToStartStream2)
                {
                    TfsDisposable = TfsDisposable ?? hotObs2.Connect();
                }
            })
            .Do(a => 
            {
                // Based on condition 2 stop the second stream
                if (ConditionToStopStream2)
                {
                    TfsDisposable?.Dispose();
                    TfsDisposable = null;
                }
            }).Publish();
    
    
            // Merge both the stream using Combine Latest
            var finalMergedData  = hotObs.CombineLatest(hotObs2, (a, b) => { return string.Format("{0}, {1}", a, b); });
    
            // Display the result
            finalMergedData.Subscribe(a => { Console.WriteLine("result: {0}", a);  });
    
            // Start the first hot observable
            observerHot.Connect();
    

1 个答案:

答案 0 :(得分:1)

玩这个:

var hotObs = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1.0));
var hotObs2 = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(0.3));

var query =
    hotObs2.Publish(h2s =>
        hotObs.Publish(hs =>
            hs
                .Select(a => a % 7 == 0 ? h2s : Observable.Empty<long>())
                .Switch()
                .Merge(hs)));

这需要两个observable并使用在lambda中发布它们的重载来发布它们。它使它们在lambda的范围内变得热,并且可以防止管理.Connect()的调用。

然后我只是执行条件检查(在这种情况下是a偶数),然后返回另一个流,如果没有返回空流。

然后.Switch仅将IObservable<IObservable<long>>转换为IObservable<long>,只接受来自最新内部可观察量的值。

最后,它与原始hs流合并。

使用上面的示例代码,我得到以下输出:

0 
1 
2 
3 
1 
2 
3 
4 
5 
6 
7 
23 
24 
25 
8