Async Yield Return thanks to IAsyncEnumerable
General description of yield return:
When you use the
yield return statement in your code, you indicate that the method, operator, or get accessor in which the
yield return keyword appears is an iterator. The
yield return statement will return one element in a collection at a time.
The result returned from a
yield return iterator method can be consumed by using a foreach statement or LINQ query. Each iteration of the foreach loop calls the iterator method. When a
yield return statement is reached in the iterator method, the result is returned and the current location in the iterator method is retained. Upon the execution of the next element in the foreach loop, the iterator method is restarted from the retained location the next time that the iterator method is called.
Standard yield Example:
The following code
var i = 0;
var list = new List<int>();
foreach(var number in GenerateWithoutYield())
can be refactored to make use of the
yield return statement as follows:
var i = 0;
yield return ++i;
foreach(var number in GenerateWithYield())
Async yield return:
When working with asynchronous code using async/await, the use of the
yield return statement requires just a few small adjustments to your code. Using an async
yield return statement requires that the method be asynchronous, making use of async/await.
Usually an async method will return a task. Your first thought when using
yield return in your async method may be to have the method return Task of IEnumerable. However, this is not allowed when using
yield return, instead your async
yield return method must return an
You also cannot await your new async
yield return method that returns an
IAsynEnumerable. Instead, yo must await the foreach statement instead. This is becuase
IAsyncEnumerable does not have a GetAwaiter() method.
IAsyncEnumerable is an async iterator.
private async void ReadTheFile()
var path = Path.Combine(Environment.CurrentDirectory, "file.txt");
var lines = GetTxtLinesFromFile(path);
// do something with read-in lines
await foreach (var line in lines)
async IAsyncEnumerable<string> GetTxtLinesFromFile(string filePath)
StreamReader file = new System.IO.StreamReader(filePath);
while ((line = await file.ReadLineAsync()) != null)
yield return line;