采用以下方法:
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
。
对于我自己,我可以想象两种方法:
- 迭代
IAsyncEnumerable
并立即将结果 yield 回去。
await foreach(var item in Bar())
{
yield return item;
}
- 创建一个结构体来暂存
IAsyncEnumerable
,这似乎是更好的解决方案,但仍然有点过度设计。
IAsyncEnumerable
,这似乎是更好的解决方案,但仍然有点过度设计。return new AsyncEnumerableHolder<int>(Bar());
public struct AsyncEnumerableHolder<T>
{
public readonly IAsyncEnumerable<T> Enumerable;
public AsyncEnumerableHolder(IAsyncEnumerable<T> enumerable)
{
Enumerable = enumerable;
}
}
有没有更好的方法来实现这个行为?
async
希望你返回void
、Task
或Task<T>
(但是void
在这种情况下几乎总是错误的选择)。 - Powerlordpublic async IAsyncEnumerable<int> Bar()
在语法上是完全有效的。我不确定你想说什么。 - Twentyasync
仅支持某些返回类型。将IAsyncEnumerable<T>
作为返回类型应该会导致编译器出错,因为它没有声明GetAwaiter
方法。 - PowerlordIAsyncEnumerable<T>
和IAsyncEnumerator<T>
返回类型在C#8中肯定是受支持的 - 异步流。 - Ivan Stoev