Subscribe to Observable.Retry() doesn't return until it completes?

放肆的年华 提交于 2019-12-11 04:36:24

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/20212951/subscribe-to-observable-retry-doesnt-return-until-it-completes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!