簡體   English   中英

IEnumerable <T> .Count()實際上適用於IObservable <T> ?

[英]Does IEnumerable<T>.Count() actually work for IObservable<T>?

是否有示例向我展示Observable.Count<TSource> Method實際工作方式? 我提出的示例似乎返回包裝在可觀察值中的計數,而不是預期計數。

例如,我希望從中返回1

System.Diagnostics.Debug.WriteLine((Observable.Return<string>("Hello world!")).Count());

將來會返回1 (因為畢竟這是一個異步序列)? 還是我缺少一些基本的東西? 在撰寫本文時,我實際上假設.Count()將返回T的結果,並且隨着時間的推移會不斷增長。 真? 是。

Rx中的聚合運算符與LINQ中的聚合運算符有所不同-它們不會立即返回值,而是返回將來的結果 (即,一旦Observable完成,我們只能知道最終的Count是什么)。

因此,如果您寫:

Observable.Return("foo").Count().Subscribe(x => Console.WriteLine(x));
>>> 1

因為畢竟這是一個異步序列

這實際上並非完全正確。 在這里,只要有人打電話給Subscribe ,一切都將立即運行。 上面的代碼沒有異步的地方,沒有多余的線程,所有事情都在訂閱服務器上發生。

我認為使用可立即返回的observable 以及像rasx在注釋中一樣使用async / await語法會使事情變得相當混亂。

讓我們創建一個包含5個元素的流,這些元素每秒返回一次,然后完成:

private IObservable<long> StreamWith5Elements()
{
    return Observable.Interval(TimeSpan.FromSeconds(1))
                     .Take(5);
}

我們可以使用異步/等待魔術來調用它,如下面的LINQPad友好示例所示:

void Main()
{
    CountExampleAsync().Wait();
}

private async Task CountExampleAsync()
{
    int result = await StreamWith5Elements().Count();
    Console.WriteLine(result);
}

但這誤導了這里發生的事情IObservable<int> Count()返回IObservable<int> ,但是Rx對await超級友好,並將結果流轉換成Task<int> -然后await將該任務的int結果移回。

當對IObservable<T>使用await時,您隱式地說,您希望observable可以使用單個結果調用OnNext() ,然后調用OnComplete() 實際發生的情況是,您將獲得Task<T> ,該Task<T>返回在流終止之前發送的最后一個值。 (類似於AsyncSubject<T>行為)。

這很有用,因為它意味着任何流都可以映射到Task ,但是確實需要仔細考慮。

現在,上面的示例等效於以下更傳統的Rx:

void Main()
{
    PlainRxCountExample();
}

private void PlainRxCountExample()
{
    IObservable<int> countResult = StreamWith5Elements().Count();
    countResult.Subscribe(count => Console.WriteLine(count));

    /* block until completed for the sake of the example */
    countResult.Wait();
}

在這里,您可以看到Count()確實返回了int流-提供異步計數。 僅在源流完成時才返回。

在Rx的早期,Count()實際上是同步的。

但是,這並不是一個非常有用的狀態,因為它“退出Monad”-即使您脫離IObservable<T>並阻止您進一步使用Rx運算符。

一旦開始“在流中思考”,Count()的異步特性實際上就非常直觀了,因為當然,您只能在流完成時提供一個流的計數,為什么還要為此而徘徊呢? :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM