C# has support for iterator methods and async methods. Still, no support for a method that is both an iterator and an async method, or you can say iterate a collection asynchronously. In C# 8.0, you can create and consume streams asynchronously. A method that returns an asynchronous stream has the following properties.
async
modifier.IAsyncEnumerable<T>
, it is similar to the IEnumerable<T>
method used to iterate over a collection, except that IAsyncEnumerable<T>
allows us to move through the collection asynchronously.IAsyncEnumerable<T>
allows us to wait for the next element in the collection without blocking a thread.yield
return statements to return successive elements in the asynchronous stream.Let's consider the following simple method, which creates and consume an asynchronous stream and returns IAsyncEnumerable<T>
.
private static async IAsyncEnumerable<int> GenerateEvenSequence()
{
for (int i = 0; i <= 50; i = i + 2)
{
await Task.Delay(100);
yield return i;
}
}
The above example generates a sequence of even numbers from 0 to 50, waiting 100 ms between generating each even number. You would enumerate the sequence using the await foreach
statement, as shown below.
public static async Task PrintEvenSequenceAsync()
{
await foreach (var number in GenerateEvenSequence())
{
Console.WriteLine(number);
}
}
The GenerateEvenSequence()
method is asynchronous. It will return all of these numbers at once, not one by one as they are generated. The yield
keyword can perform stateful iteration and return each collection element one by one.