Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are these Rx sequences out of order?

Suppose I write

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

The sequence produced is 1 1 2 1 2 3 as expected. But now if I write

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

Now the sequence produced is 1 1 2 1 2 1 3 2 3 4 instead of what one would expect 1 1 2 1 2 3 1 2 3 4. Why is that? Does SelectMany() do some kind of multithreaded merge?

like image 937
Dmitri Nesteruk Avatar asked Mar 10 '17 09:03

Dmitri Nesteruk


1 Answers

Observable.Range() itself will always generate its events in order. However SelectMany() doesn't wait for the previous observable to complete before starting the next one. Which means that as the sequences get longer, there will be more and more overlap, since the next sequence will start before the previous has completed and so on.

If you are trying to get the output to be sequential, then you will need to use a different means of flattening the sequence, such as Concat().

E.g:

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

Output: 1,1,2,1,2,3,1,2,3,4

Unlike SelectMany(), Concat() does wait for each sequence to complete before starting the next one.

like image 145
Brandon Kramer Avatar answered Sep 24 '22 14:09

Brandon Kramer