Passing through IAsyncEnumerable<T> within an async method body #5827
-
Using an async on a method signature with a return of IAsyncEnumerable forces you to yield each item back instead of being able to pass through the original async enumerable. This is not just an issue isolated to myself but seems to be a common theme on stackoverflow
Steps to reproduceGiven the following code example. public async IAsyncEnumerable<ComplexObject> Execute(IAsyncEnumerable<ComplexObject> data)
{
// do something which requires an await here
return data; //causes compile error CS1622
} Expected behaviourCode compiles and passes through Actual behaviourCompile error CS1622 WorkaroundIterating through the enumerable will allow compilation public async IAsyncEnumerable<ComplexObject> Execute(IAsyncEnumerable<ComplexObject> data)
{
await foreach (var item in data)
yield return item;
} ScenarioWe could easily workaround the above by just returning an IEnumerable in most cases, however imagine the scenario where we need to do some kind of aggregation with the data in a pipeline design pattern which returns IAsyncEnumerable. public async IAsyncEnumerable<ComplexObject> Execute(IAsyncEnumerable<ComplexObject> data)
{
var totalAmount = await data.SumAsync(x => x.Amount);
// do something with this aggregated data
// forced to write a foreach which yields each item
await foreach (var item in data)
yield return item;
} Questions
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 9 replies
-
Remove the public IAsyncEnumerable<ComplexObject> Execute(IAsyncEnumerable<ComplexObject> data)
{
return data;
} As an iterator you are expected to yield each individual value. You can't return an |
Beta Was this translation helpful? Give feedback.
-
Return a |
Beta Was this translation helpful? Give feedback.
-
Possibly. Though this might mask some bug. Perhaps you have an |
Beta Was this translation helpful? Give feedback.
Remove the
async
modifier if you don't want the method to behave as an iterator:As an iterator you are expected to yield each individual value. You can't return an
IAsyncEnumerable<T>
just as synchronous iterators can't returnIEnumerable<T>
and normalasync
methods can't returnTask<T>
.