【问题标题】:A code example illustrating the difference between the paradigms of async/await and Reactive (Rx) extension?一个代码示例说明 async/await 和 Reactive (Rx) 扩展范式之间的区别?
【发布时间】:2023-03-10 08:31:01
【问题描述】:

System.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 的情况下,Rx 中缺少什么可能会导致执行同样的操作更加笨拙或效率更低(即仅使用原生 .NET Iobservable/IObserver + await/async 方法),有哪些可能的说明?

【问题讨论】:

  • 你用谷歌搜索过这个吗?显示没有任何迹象表明你有。
  • @fredrik,我应该如何证明上面没有 google SERP 结果?
  • 只需说出您搜索过的内容并且没有产生任何结果。对我来说,这将表明您至少尝试过。
  • closest result 告诉我们为什么要在 Rx 中使用 await/async。但这并不能解释为什么在首先使用 async/await 之后还要使用 Rx
  • 你不应该在没有 Rx 的情况下使用原生 .NET IObservable/IObserver

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


【解决方案1】:

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

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

不可组合: |单品 |多个项目 ------|----------------|---------------- 同步 |功能 |可迭代 异步 |异步函数 |可观察的 可组合: |单品 |多个项目 ------|-----------|-------- --------- 同步 |高阶函数 | Linq/Ramda/java.util.stream 异步 |未来/承诺 | Rx 可观察的

请注意,根据实现,您可以拥有可以同步或异步操作的期货和 rx 可观察对象,具体取决于您尝试对它们执行的操作是同步的还是异步的

【讨论】:

    【解决方案2】:

    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> 也是一个具体类型,因为 Rx 使用接口将您从实现中抽象出来。我发现这有助于单元测试。 TaskCompletionSource<T> 但是在使用任务进行测试时有助于避免隐式并发。

    最后,除了 Rx 处理值序列(不是单个值)的主要区别之外,Rx 还被设计为与 LINQ 一起使用,以提供似乎与序列(无论是在休息时像IEnumerable<T>,或者像IObservable<T>一样运动。

    最终,这些是针对略有不同工作的不同工具。有一些重叠,所以你有时可以用一个来做另一个更擅长的事情。具体来说,我认为Task 更擅长将异步工作单元组合在一起(执行此操作,然后执行此操作,然后执行此操作),而 Rx 更擅长将事件序列组合在一起(当此事件发生时,执行此操作来自其他事件的数据)。

    【讨论】:

    • 多个值不需要Task<T[]>,多个值可以使用Task<IEnumerable<T>>也可以使用INotifyCollectionChanged接口。
    • 正如所指出的“..返回值的集合/数组/列表..”。并且讨论不是关于事件(与 RX 更密切相关),而是关于RxTask 之间的比较。添加事件、APM、线程、回调和其他异步样式确实会引起非常大的讨论,甚至是一本书。 ;-)
    • “当这个事件发生时,用来自另一个事件的数据来做这件事”,这让我很难受。我终于开始了解这个概念了,谢谢!前几天我试图在 React 中使用钩子来做到这一点,但是如果没有顺序代码,我想不通怎么做,我想我应该看看 RxJs
    【解决方案3】:

    【讨论】:

    • +1。另请注意,它们可以很好地协同工作:Task<T>.ToObservable() 创建一个最多只产生一个结果的IObservable<T>await myObservable 允许您异步等待可观察对象的最后一个元素。
    • @StephenCleary,您能否设法拍摄相同(或不同)的答案?
    猜你喜欢
    • 2011-05-03
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 2012-05-04
    • 1970-01-01
    • 2014-02-23
    • 2014-01-06
    相关资源
    最近更新 更多