Return IAsyncEnumerable from an async method

橙三吉。 提交于 2020-05-15 09:23:05

问题


Take the following the methods:

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

I wonder what the best practice would be, to do, what the code above tries to. Basically returning an IAsyncEnumerable from an async method.

For myself I can imagine two ways:

  1. Iterating over the IAsyncEnumerable and yielding the result immediately back.
await foreach(var item in Bar())
{
    yield return item;
}
  1. Creating a struct which can store an IAsyncEnumerable temporarily, which seems to be the better solution, but still kind of overkill.
return new AsyncEnumerableHolder<int>(Bar());

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

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

Is there any better way to achieve this behavior?


回答1:


The struct approach wouldn't work. If you want to asynchronously return an IAsyncEnumerator<T> value, you could use Task<IAsyncEnumerator<T>> with return Bar();. However, that would be unusual. It would be much more natural to create a new IAsyncEnumerator<T> that incorporates await SomeAsyncMethod() at the beginning of the asynchronous enumerable. To do this, you should use await and yield as suggested by your option (1):

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

On a side note, JavaScript has a very nice yield* syntax for this kind of "enumerate this whole sequence into my result sequence" concept, and it supports both synchronous and asynchronous sequences. C# does not have this kind of syntax for either synchronous or asynchronous sequences.



来源:https://stackoverflow.com/questions/59689529/return-iasyncenumerable-from-an-async-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!