Dmitri Nesteruk
Dmitri Nesteruk

Reputation: 23798

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?

Upvotes: 5

Views: 631

Answers (1)

Brandon Kramer
Brandon Kramer

Reputation: 1118

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.

Upvotes: 8

Related Questions