Rx.NET 中的 Wait 运算符是做什么的?

What does the Wait operator in Rx.NET do?

在 Rx.NET 库的 v2.2.5 中,有一个名为 Wait 的运算符定义如下:

public virtual TSource Wait<TSource>(IObservable<TSource> source)

class library reference on MSDN nor this page 均未提及此运算符。

从它的实现来看,这有点太麻烦了,我猜它会等待可观察对象生成它的所有元素,如果可观察对象有任何元素,则 returns 最后一个元素,并且如果没有,它 returns default(TSource)。但是我不确定。

如果这是正确的,那么它与 LastOrDefaultAsync 有何不同?

它实际上有什么作用?

intellisense 文档看起来相当准确

Waits for the observable sequence to complete and returns the last element of the sequence. If the sequence terminates with an OnError notification, the exception is thrown.

https://github.com/Reactive-Extensions/Rx.NET/blob/master/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs#L493

所以运算符将阻塞调用线程(YUCK!)直到序列完成,然后产生最后一个值。

LastOrDefaultAsync 相反 returns 和 IObservable<T> 所以不阻塞。

方法的文档在 Observable class,而不是查询语言实现。

Waits for the observable sequence to complete and returns the last element of the sequence.
If the sequence terminates with an OnError notification, the exception is throw.

https://github.com/Reactive-Extensions/Rx.NET/blob/v2.2.5/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs#L493

本质上是Last<TSource>()的同义词。

Wait

Last

问题中对 Wait 的描述不完全正确。

以下是 WaitLastOrDefaultAsync 之间的相似之处:

  1. 两者在逻辑上都在等待接收源可观察对象中的所有值。但正如 Lee Cambell 在他的回答中指出的那样,Wait 阻塞了当前线程,而 LastOrDefaultAsync 则没有。

这里是 WaitLastOrDefaultAsync 之间差异的总结:

  1. 如果可观察序列中没有元素,Wait抛出异常; LastOrDefault returns default(TSource).

  2. 如果在观察observable的过程中发生了异常,Wait会通过调用observer.OnError来报告异常,但随后也会立即抛出异常; LastOrDefaultAsync 仅通过对所有订阅的观察者调用 observer.OnError 来报告异常。但是,在这两种情况下,如果出错,观察都会停止。

Rx 的源代码附带的 XML 文档(或者甚至是通过 NuGet 或通过 MSI 安装程序的二进制分发)如此解释:

Waits for the observable sequence to complete and returns the last element of the sequence. If the sequence terminates with an OnError notification, the exception is throw.

异常

如果 source 为 null,则抛出 ArgumentNullException

如果 source 序列为空,则抛出 InvalidOperationException