Task<T>.ContinueWith
和 IObservable<T>.Subscribe
有着相同的基本概念。它们非常相似,以至于 Reactive Extension 提供了一个转换扩展方法。由于 IObservable<T>
是 BCL 的一部分,因此没有理由不实现 IObservable<T>
。那么,为什么 Task<T>
没有实现 IObservable<T>
呢?
Task<T>.ContinueWith
和 IObservable<T>.Subscribe
有着相同的基本概念。它们非常相似,以至于 Reactive Extension 提供了一个转换扩展方法。由于 IObservable<T>
是 BCL 的一部分,因此没有理由不实现 IObservable<T>
。那么,为什么 Task<T>
没有实现 IObservable<T>
呢?
这篇文章由Rx团队在他们的2.0测试版博客中讲述得非常好。虽然这是一篇非常长的文章,但里面有很多很棒的信息。
简略总结= IObservable用于未来结果的序列,Task用于单个未来结果
我认为最好解释了它们之间关系的图表在该帖子中,但可惜它在文章中太深了(而且我提到过,那篇文章非常大 :)
虽然整篇文章都值得阅读(依我之见),但与Rx / Task / async/await如何配合开始的相关文本标题为“Rx v2.0和.NET 4.5 “async” / “await” - 更好的协作故事”
IEnumerable<T>
的情况下代码有什么问题;然而,我不明白为什么 Task<T>
实现 IObservable<T>
是错误的,因为它应该在逻辑上实现它,因为它包含相同的方法,并且不会导致像将每个单独的值视为可枚举一样的可怕代码。 - user1377345Task<T>
和IObservable<T>
实际上并没有相同的基本概念。是的,两者都是异步的,但这几乎是它们之间所有共同点的终点。两者之间的主要区别在于,Task<T>
始终具有单个值,而IObservable<T>
可以拥有尽可能多的值(包括零或少量)。
如果Task<T>
实现了IObservable<T>
,那么这将类似于.Net中每个实现IEnumerable<T>
,返回单个结果,即该对象本身。
将Task<T>
转换为IObservable<T>
是微不足道的。可以使用Rx中的ToObservable()
扩展方法,也可以通过自己编写来完成。这使得你所要求的变得不太必要。
Task
是可观测的,但它是单个值的可观测对象。IObservable
表示多个可观测值。我认为这并不不正确,这些就是两种类型的定义。 - svickint
应该实现 IEnumerable<int>
。我不认为这是一个好主意,所以我认为 Task
也不应该实现 IObservable
。 - svickIEnumerable<T>
,就像一个简单的值不应该实现 IObservable<T>
一样。任务(Task)和简单值之间有很大的区别,任务代表着可能会失败的操作。因此它是可观察的。这更类似于让 Nullable<T>
实现 IEnumerable<T>
,这是有些意义的。 - Patrik HägneTask<T>
实现IObservable<T>
会有什么缺点?即使您的推理成立,我也看不出任何缺点,只有好处。 - Patrik Hägne“FT” 的含义不确定,除了 MSFT 是纳斯达克股票代码代表微软公司之外,"MS" in "MSFT" 显然是指微软。事实上,尽管
Task<TResult>
目前尚未实现IObservable<T>
接口,但它实际上非常适合实现该接口。可观察对象表示由任意数量的值组成,以流的结束或异常为终止。而Task<TResult>
恰好符合这种描述:它要么完成一个单独的值,要么抛出异常。虽然未来的 .NET Framework 版本可能会看到Task<TResult>
实现IObservable<T>
接口,但我们可以通过将其作为Task<TResult>
的扩展方法来实现相关行为;实际上,Rx 和ParallelExtensionsExtras
都包含了这样的扩展方法。
原因是,虽然Task<T>
类型在.NET框架中,但反应式扩展(Rx)和IObservable<T>
不在其中。 System.Reactive
程序集具有System.Threading.Tasks
作为依赖项,因此后者中没有任何内容可以引用前者。
如果将来他们将Rx添加到.NET中,他们可能会像您建议的那样做。
实际上,我可能说得太快了。请查看文档。在.NET 4和4.5中,IObservable<T>
接口实际上存在于mscorlib
程序集中。因此,我上面说的不是完全有效的原因。我正在修订我的猜测原因为“因为他们尚未将Rx集成到.NET中”,而不是“由于循环依赖关系目前不可能”。