一个代码示例说明了async / await和Reactive(Rx)扩展的范例之间的区别?

时间:2013-04-08 10:35:16

标签: c# task-parallel-library system.reactive async-await c#-5.0

系统。Reactive extension for .NETnew C# 5.0 (.NET 4.5) async/await都追求(或基于)future and promises constructs范式(方法)。

你能给出(*)最简单的C#代码示例来说明它们之间的区别吗?

(*)
没有I / O,互联网或数据库连接是否可能?

更新
好吧,如果以前似乎回答了这个问题,让我重新制定一下 为什么在使用本机.NET Iobservable / IObserver + await/async时会添加并开始使用.NET的Reactive(Rx)扩展?

如果没有Rx(即只使用原生的.NET Iobservable / IObserver + await / async方法),Rx中缺少哪些内容可能会更加笨拙或效率更低?

3 个答案:

答案 0 :(得分:15)

Future / Promise范例通常用于在未来返回单个值。可能需要一些繁重的计算或IO,因此无法保证及时同步返回。

Rx(以及代理IObserver<T> / IObservable<T>接口)是可观察序列的范例。正如同步方法可以返回单个值(int)一样,它也可以返回带有一个值的IEnumerable<int>。将此与异步世界进行比较,Task<int>可以返回单个int值,IObservable<int>可以返回只有一个int值的序列。

因此,如果您想要使用Task<T>返回一系列值,则必须创建某种延续,或者返回值T的集合/数组/值列表,例如Task<int[]>Task。但这意味着您可以获得全部或非全部值。

Task<T> / TaskCompletionSource<T>也是一种具体类型,其中Rx使用接口从实现中抽象出来。我发现这有助于单元测试。但是,在使用任务进行测试时,IEnumerable<T>可以帮助避免隐式并发。

最后,除了Rx处理值序列(不是单个值)的主要区别之外,Rx还设计为与LINQ一起使用,以提供查询和组合优势,这些优点似乎与序列非常有效(在静止时例如IObservable<T>,或像Task这样的动作。

最终,这些是针对略有不同的工作的不同工具。有一些重叠,所以你有时可以使用一个来做另一个更好的。具体来说,我认为{{1}}更好地组合异步工作单元(这样做,然后这样做,然后这样做),其中Rx更好地组合事件序列(当这个事件发生时,使用此其他事件的数据执行此操作)。

答案 1 :(得分:5)

我喜欢Reactive文档中的表:http://reactivex.io/intro.html

我有自己的想法,我添加了第三维不可组合/可组合。

Non-composable:

       |  Single Item   | Multiple items
 ------|----------------|----------------
 Sync  | Function       | Iterable
 Async | Async function | Observable

Composable:

       |      Single Item      |       Multiple items
 ------|-----------------------|----------------------------
 Sync  | Higher order function | Linq/Ramda/java.util.stream
 Async | Future/promise        | Rx observable

请注意,根据实现情况,您可以使用可以同步或异步执行的future和rx observable,具体取决于您尝试使用它们是同步还是异步

答案 2 :(得分:4)