Reputation: 66541
I expect IObservable.Subscribe
to be asynchronous: whatever happens inside, I would like my subscription back.
But Retry
seems to have a different semantic:
var retry = Observable.Throw(new Exception(), 0).Retry();
Console.WriteLine("got here");
var subscription = retry.Subscribe();
Console.WriteLine("didn't get here, ever");
There is clearly something I don't understand here. I guess using Retry with no parameters can't be used very often, or it should be used for something that I haven't thought of.
Upvotes: 1
Views: 175
Reputation: 29786
The problem isn't anything to do with Retry
- it's Observable.Throw
because it defaults to scheduling its OnError
on the immediate scheduler. Change your first line to this and you are golden:
var retry = Observable.Throw<int>(new Exception(), Scheduler.Default).Retry();
In general Rx tries to use the most immediate scheduler it can. Scheduler.Default
will use the current platform's preferred scheduler that introduces concurrency.
Retry
will initially subscribe on the current thread (which is fine) and then subscribe for each retry on whatever thread Throw
terminates on.
EDIT
Although the fix above works - it's probably not the best way. It's actually good that Throw
and Retry
try to use the immediate scheduler as this is the most computationally efficient way. The code above will cause every iteration of Throw
to run on a different thread.
A better and more idiomatic Rx solution would be to edit the third line instead:
var subscription = retry.SubscribeOn(Scheduler.Default).Subscribe();
This causes only the initial subscription to Retry
to happen asynchronously on a different Thread - and the rest of the processing will stay on that one thread.
Upvotes: 1