我对与这段代码类似的一系列可观察数据进行了同步订阅:
integers.Where(id => (id & 1) == 0).Subscribe(id => evenHandler.LRP(id, RandomDelay()));
integers.Where(id => (id & 1) == 1).Subscribe(id => oddHandler.LRP(id, RandomDelay()));
问题是操作是阻塞的,所以你最终会遇到这样的情况:
OddHandler running with ID 1 for 331ms...
EvenHandler running with ID 2 for 651ms...
OddHandler running with ID 3 for 391ms...
EvenHandler running with ID 4 for 633ms...
OddHandler running with ID 5 for 197ms...
我希望操作以异步方式运行,并且我无法访问公开方法IHandler
的{{1}}接口。经过一些研究后,似乎至少有两种方法可以使用RX来实现这一点:
方法1:
LRP
方法2:
integers.Where(id => (id & 1) == 0)
.Select(async id => await Task.Run(() => evenHandler.LRP(id, RandomDelay())))
.Subscribe();
integers.Where(id => (id & 1) == 1)
.Select(async id => await Task.Run(() => oddHandler.LRP(id, RandomDelay())))
.Subscribe();
两种方法出现以生成相同的结果。
我的问题:
答案 0 :(得分:0)
我会远离方法1 ,因为它会“破坏”Rx。当你在number_of_subs_made
内@app.route('/status/<int:jobid>')
def check_status(jobid):
return StatusOfTheWorkBeingCarriedOut(jobid)
进行同步操作时,异步工作。每当你想要异步时,把它放在await
里面。 Select
甚至直接接受SelectMany
。
在方法2 中,您将SelectMany
包装在一个observable中。我相信这与Task<T>
非常相似。然而,创建一个Task
然后将其转换为可观察对象有点沉重;你可以直接使用一个observable:
Observable.FromAsync()
这将创建一个observable,在内部工作完成时返回Task
。我还指定它应该在integers.Where(id => (id & 1) == 0)
.SelectMany(id => Observable.Start(
() => evenHandler.LRP(id, RandomDelay()),
ThreadPoolScheduler.Default))
.Subscribe();
integers.Where(id => (id & 1) == 1)
.SelectMany(id => Observable.Start(
() => oddHandler.LRP(id, RandomDelay()),
ThreadPoolScheduler.Default))
.Subscribe();
上运行,这使它在Unit
内运行。