14 Generating collections asynchronously – await foreach and IAsyncEnumerable
This chapter covers:
- How await foreach works.
- Using yield return in async methods
- Iterating over asynchronous data using IAsyncEnumerable<T> and await foreach.
Since its inception, the C# language has featured the foreach keyword, offering a straightforward and concise way to loop through elements in a collection. With C# 2, Microsoft introduced the yield return keyword, which simplifies the dynamic generation of sequences that can be iterated with foreach (we discussed yield return back in chapter 2). In C# 8, Microsoft enhanced this functionality by allowing yield return to be used with await, allowing us to use similar syntax to write asynchronous code.
In this chapter we’ll see how the asynchronous version of foreach (called await foreach) and the asynchronous version of yield return work and how we can use them to write simple code that processes data we generate (or retrieve) asynchronously.
14.1 Iterating over an asynchronous collection
To understand how the asynchronous await foreach works we need to first take a look at the good old non-asynchronous foreach. The foreach keyword is “syntactic sugar”, it’s just a nicer way to write code relative to using more basic language features, specifically, foreach is just a nicer way to write a while loop. You can think of the compiler’s implementation of foreach as a simple text replacement, the compiler takes code like this: