在RX中如何组合两种不同类型的来源

时间:2012-01-21 01:35:58

标签: system.reactive reactive-programming

设置:

  • 首先IObservable生成 A
  • 类型的值
  • 第二个IObservable生成 B
  • 类型的值
  • 他们以不同的速度产生价值(非常快,最多每10毫秒)

我想要实现的目标:

每个 N 时间(N非常慢,大约500毫秒)必须对服务进行调用,并提供来自 First Second的最新值 IObservable

问题: 我想知道如何使用RX。

当前解决方案(不工作)

var stateObs = from drag in dragObs.MostRecent(0).ToObservable()
                from roll in rollObs.MostRecent(0).ToObservable()
                select new ClientState
                            {
                                FileDragPerc = drag,
                                PhoneRoll = roll,
                                PendingFileType = FileType.Image,
                                TransferState = TransferState.SelectiveTransfer
                            };

stateObs.Sample(TimeSpan.FromMilliseconds(300))
        .Subscribe(x => _lsService.SetClientStateAsync(x),
                    x => Debug.WriteLine("Error in observable "),
                    () => Debug.WriteLine("Error observable finished! "));

2 个答案:

答案 0 :(得分:2)

你是对的。这就是CombineLatest运算符的作用:

A: 1...2...3...4...5...

B: a.....b.........c...

保留任一序列的最后一个值以生成选择器作用的对。输出流将为(1,a) (2,a) (2,b) (3,b),依此类推。

如果你必须从任一流构建正确的对,请使用'Zip'运算符,它将为您提供(1,a) (2,b) (3,c)等等。

P.S。

我建议尝试更好地理解编译器如何重写查询理解。它将解决你的大部分困惑。

from a in oA
from b in oB
select ...

实际上是SelectMany(oA, oB)

答案 1 :(得分:1)

我想我自己找到了答案

CombineLatest()操作做我需要的, 这就是我得到的:

var stateObs = dragObs.CombineLatest(rollObs, (d, r) => new ClientState
                                                       {
                                                           FileDragPerc = d,
                                                           PhoneRoll = r,
                                                           TransferState = TransferState.SelectiveTransfer,
                                                           PendingFileType = FileType.Image
                                                       });

    stateObs.Sample(TimeSpan.FromMilliseconds(300))
            .Subscribe(x => _lsService.SetClientStateAsync(x),
                        x => Debug.WriteLine("Error in observable "),
                        () => Debug.WriteLine("Error observable finished! "));