user981225
user981225

Reputation: 9252

Observing an asynchronous sequence with 'yield return'

The following sample works fine:

static IEnumerable<int> GenerateNum(int sequenceLength)
    {
      for(int i = 0; i < sequenceLength; i++)
      {
          yield return i;
      }
    }

static void Main(string[] args)
    {

        //var observ = Observable.Start(() => GenerateNum(1000));
        var observ = GenerateNum(1000).ToObservable();

        observ.Subscribe(
            (x) => Console.WriteLine("test:" + x),
            (Exception ex) => Console.WriteLine("Error received from source: {0}.", ex.Message),
            () => Console.WriteLine("End of sequence.")
            );

        Console.ReadKey();
    }

However, what I really want is to use the commented out line - i.e. I want to run the 'number generator' asynchronously, and every time it yields a new value, I want it to be output to the console. It doesn't seem to work - how can I modify this code to work?

Upvotes: 4

Views: 1808

Answers (1)

Joshua Honig
Joshua Honig

Reputation: 13215

When doing this for asynchronous execution in a console app, you may want to use the ToObservable(IEnumerable<TSource>, IScheduler) overload (see Observable.ToObservable Method (IEnumerable, IScheduler)). To use the built-in thread pool schedule, for example, try

var observ = GenerateNum(1000).ToObservable(Scheduler.ThreadPool);

It works for me...To expand, the following complete example works exactly as I think you intend:

    static Random r = new Random();

    static void Main(string[] args) {

        var observ = GenerateNum(1000).ToObservable(Scheduler.ThreadPool );

        observ.Subscribe(
            (x) => Console.WriteLine("test:" + x),
            (Exception ex) => Console.WriteLine("Error received from source: {0}.", ex.Message),
            () => Console.WriteLine("End of sequence.")
            );

        while (Console.ReadKey(true).Key != ConsoleKey.Escape) {
            Console.WriteLine("You pressed a key.");
        }
    } 

    static IEnumerable<int> GenerateNum(int sequenceLength) {
        for (int i = 0; i < sequenceLength; i++) {
            Thread.Sleep(r.Next(1, 200));
            yield return i;
        }
    }

Upvotes: 7

Related Questions