为什么这些Rx序列乱序?

时间:2017-03-10 09:52:13

标签: c# .net system.reactive reactivex rx.net

假设我写了

var gen = Observable.Range(1, 3)
  .SelectMany(x => Observable.Range(1, x));

按预期生成的序列为1 1 2 1 2 3。但现在如果我写

var gen = Observable.Range(1, 4)
  .SelectMany(x => Observable.Range(1, x));

现在生成的序列为1 1 2 1 2 1 3 2 3 4,而不是人们所期望的1 1 2 1 2 3 1 2 3 4。这是为什么? SelectMany()是否进行某种多线程合并?

1 个答案:

答案 0 :(得分:5)

Observable.Range()本身将始终按顺序生成事件。但是SelectMany()在开始下一个observable之前不会等待前一个observable完成。这意味着随着序列变长,会有越来越多的重叠,因为下一个序列将在前一个序列完成之前开始,依此类推。

如果您尝试将输出变为顺序输出,则需要使用不同的方法来展平序列,例如Concat()

E.g:

var gen = Observable.Range(1, 4)
  .Select(x => Observable.Range(1, x)).Concat();

产出:1,1,2,1,2,3,1,2,3,4

SelectMany()不同,Concat() 等待每个序列在开始下一个序列之前完成。