【问题标题】:Return IAsyncEnumerable from an async method从异步方法返回 IAsyncEnumerable
【发布时间】:2020-04-28 13:36:46
【问题描述】:

采取以下方法:

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;
    }
}

有没有更好的方法来实现这种行为?

【问题讨论】:

  • 很确定async 期望您返回voidTaskTask&lt;T&gt;(尽管void 几乎总是错误的选择)
  • 好吧,public async IAsyncEnumerable&lt;int&gt; Bar() 在语法上是完全有效的。我不确定你想说什么。
  • 我想说的是async只支持certain return types。将IAsyncEnumerable&lt;T&gt; 作为返回类型应该 是编译器错误,因为它没有声明GetAwaiter 方法。
  • 这是我绝对需要 X 的另一个问题,因为我认为这是我问题的答案,但是,X 不起作用。相反,您应该解释您要达到的目标,当然还有其他选择。
  • @Powerlord 好吧,IAsyncEnumerable&lt;T&gt;IAsyncEnumerator&lt;T&gt; 在 C#8 中绝对支持返回类型 - Asynchronous streams

标签: c# async-await c#-8.0 iasyncenumerable


【解决方案1】:

结构方法行不通。如果您想异步返回一个IAsyncEnumerator&lt;T&gt; 值,您可以Task&lt;IAsyncEnumerator&lt;T&gt;&gt;return Bar(); 一起使用。然而,这将是不寻常的。在异步枚举的开头创建一个新的IAsyncEnumerator&lt;T&gt; 合并await SomeAsyncMethod() 会更自然。为此,您应该按照选项 (1) 的建议使用 awaityield

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

附带说明,对于这种“将整个序列枚举到我的结果序列”概念,JavaScript 有一个非常好的yield* 语法,它支持同步和异步序列。 C# 没有这种用于同步或异步序列的语法。

【讨论】:

  • 感谢那个,再次迭代它感觉很不对劲。我真的希望 yield* 或类似的东西都能到达 C#。
  • @Twenty:有兴趣可以关注this issue
猜你喜欢
  • 2020-10-04
  • 2011-09-06
  • 2021-05-01
  • 2020-06-21
  • 2012-09-05
  • 2019-09-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
相关资源
最近更新 更多