2
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public static void Main()
        {
            Run().GetAwaiter().GetResult();
            Console.WriteLine("Press any key ...");
            Console.ReadKey();
        }

        private static async Task Run()
        {
            await Task.Delay(1);

            var dst = new Subject<int>();
            var res = dst
                .SelectMany(async arg =>
                {
                    await Task.Delay(1);
                    Console.WriteLine(arg);
                    return Unit.Default;
                })
                .DefaultIfEmpty();
            Observable.Range(0, 10).Subscribe(dst);

            await res;
        }
    }
}

I expect 10 numbers on the output, in reality I get none. Why?

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
mark
  • 59,016
  • 79
  • 296
  • 580

1 Answers1

3

You're not getting any values because Observable.Range(0, 10).Subscribe(dst); runs on the current thread to completion and, so by the time await res is called dst doesn't have any new values.

You can do either (1) var dst = new ReplaySubject<int>(); or (2) Observable.Range(0, 10).Delay(TimeSpan.FromSeconds(1.0)).Subscribe(dst); to get values out of your code.

Either way, this isn't trivial Rx.


I thought Lee's comment was particularly well written so I thought it was worth adding here:

i.e. Observable.Range(0, 10).Subscribe(dst); pumps 10 values into the subject immediately. Then you invoke the subscription on res. The values are gone. Subject<T> doesn't cache values. It would be like raise an event 10 times then attaching an event handler.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • 1
    i.e. `Observable.Range(0, 10).Subscribe(dst);` pumps 10 values into the subject immediately. Then you invoke the subscription on `res`. The values are gone. `Subject` doesn't cache values. It would be like raise an event 10 times then attaching an eventhandler. – Lee Campbell Jul 13 '16 at 09:48