C# 反应式扩展:将同步订阅转换为异步订阅
我对一系列可观测数据进行了同步订阅,实现方式与这段代码类似:C# 反应式扩展:将同步订阅转换为异步订阅,c#,asynchronous,system.reactive,C#,Asynchronous,System.reactive,我对一系列可观测数据进行了同步订阅,实现方式与这段代码类似: integers.Where(id => (id & 1) == 0).Subscribe(id => evenHandler.LRP(id, RandomDelay())); integers.Where(id => (id & 1) == 1).Subscribe(id => oddHandler.LRP(id, RandomDelay())); 问题是操作被阻塞,因此您以如下场景结束:
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...
我希望操作异步运行,但我无权访问公开方法LRP
的IHandler
接口。在做了一些研究之后,似乎至少有两种使用RX的方法:
方法1:
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();
方法2:
integers.Where(id => (id & 1) == 0)
.SelectMany(id => Observable.StartAsync(
async () => await Task.Run(() => evenHandler.LRP(id, RandomDelay())))
).Subscribe();
integers.Where(id => (id & 1) == 1)
.SelectMany(id => Observable.StartAsync(
async () => await Task.Run(() => oddHandler.LRP(id, RandomDelay())))
).Subscribe();
两种方法似乎产生相同的结果
我的问题是:
中等待
时,选择,您正在使同步运算符执行异步工作。每当你想做一些异步的事情时,把它放在一个SelectMany
中SelectMany
甚至直接接受任务
在方法2中,您将任务
包装在一个可观察对象中。我相信这与Observable.fromsync()
非常相似。然而,创建一个任务
,然后将其转换为一个可观察的任务,这有点繁琐;你可以直接使用一个可观察的:
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();
这将创建一个可观察对象,当内部功完成时,该对象返回一个单元
。我还指定它应该在TaskPoolScheduler
上运行,这使得它在任务中运行