Ryszard Dżegan
Ryszard Dżegan

Reputation: 25414

Observable.Create doesn't work and Observable.ToEnumerable blocks indefinitely

Why the code below doesn't work?

var observable = Observable.Create<int>(o => new Action(() =>
{
    o.OnNext(0);
    o.OnCompleted();
}));

foreach (var item in observable.ToEnumerable()) // <-- Here blocks
{
    // Never get here
}

The below doesn't work neither:

Task.Run(() =>
{
    foreach (var item in observable.ToEnumerable()) // <-- Still blocks
    {
        // Never get here
    }
}).Wait();

Interestingly, the Generate method works as expected:

var observable = Observable.Generate(0, i => i < 1, i => i + 1, i => i);

foreach (var item in observable.ToEnumerable())
{
    // Is ok
}

Upvotes: 0

Views: 296

Answers (1)

Eren Ers&#246;nmez
Eren Ers&#246;nmez

Reputation: 39085

This is incorrect:

var observable = Observable.Create<int>(o => new Action(() =>
{
    o.OnNext(0);
    o.OnCompleted();
}));

You meant to provide a function that calls OnNext upon subscription. However, you've inadvertently called the wrong overload of Observable.Create and provided it with a function which does nothing but create an action (which will be called upon disposal of the subscription). So (by mistake), you're trying to call OnNext only when the subscription is disposed.

This is what you meant to do:

var observable = Observable.Create<int>(o =>
{
    o.OnNext(0);
    o.OnCompleted();

    return () => Console.WriteLine("Disposed!"); // this will be called when 
                                                  // subscription is disposed
});

Or this:

var observable = Observable.Create<int>(o =>
{
    o.OnNext(0);
    o.OnCompleted();

    return Disposable.Empty; // using System.Reactive.Disposables;
});

Upvotes: 3

Related Questions