簡體   English   中英

從異步方法返回 IAsyncEnumerable

[英]Return IAsyncEnumerable from an async method

采取以下方法:

public async IAsyncEnumerable<int> Foo()
{
   await SomeAsyncMethod();
   return Bar(); // Throws since you can not return values from iterators
}

public async IAsyncEnumerable<int> Bar()
{
   for(int i = 0; i < 10; i++)
   {
       await Task.Delay(100);
       yield return i;
   }
}

我想知道最佳實踐是什么,上面的代碼試圖做什么。 基本上從async方法返回一個IAsyncEnumerable

對於我自己,我可以想象兩種方式:

  1. 迭代IAsyncEnumerable並立即返回結果。
await foreach(var item in Bar())
{
    yield return item;
}
  1. 創建一個可以臨時存儲IAsyncEnumerable的結構,這似乎是更好的解決方案,但仍然有點矯枉過正。
return new AsyncEnumerableHolder<int>(Bar());

public struct AsyncEnumerableHolder<T>
{
    public readonly IAsyncEnumerable<T> Enumerable;

    public AsyncEnumerableHolder(IAsyncEnumerable<T> enumerable)
    {
        Enumerable = enumerable;
    }
}

有沒有更好的方法來實現這種行為?

struct 方法不起作用。 如果你想異步返回一個IAsyncEnumerator<T>值,你可以使用Task<IAsyncEnumerator<T>>return Bar(); . 然而,這將是不尋常的。 創建一個新的IAsyncEnumerator<T>會更自然,該新IAsyncEnumerator<T>在異步枚舉的開頭合並了await SomeAsyncMethod() 為此,您應該按照選項 (1) 的建議使用awaityield

public async IAsyncEnumerable<int> Foo()
{
  await SomeAsyncMethod();
  await foreach (var item in Bar())
    yield return item;
}

附帶說明一下,對於這種“將整個序列枚舉到我的結果序列中”概念,JavaScript 有一個非常好的yield*語法,並且它支持同步和異步序列。 對於同步或異步序列,C# 沒有這種語法。

暫無
暫無

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

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