CodeBlanks Logo Icon CodeBlanks

await foreach

C# course · Advanced · Lesson 20/83

Learn to consume an async stream with await foreach.

await foreach

await foreach consumes each element of an IAsyncEnumerable<T> in order, awaiting as it goes. Declaration: await foreach (int n in Stream()) { ... }. At each iteration it awaits the next element.

This is the async counterpart of foreach. The await keyword awaits the async production of each element. This way, while input/output is waiting the thread is not blocked; the loop ends when the stream completes.

await foreach vs foreach

Synchronous foreach works on an IEnumerable<T>; it takes elements at once. await foreach works on an IAsyncEnumerable<T>; it awaits each element async.

If you try to consume an IAsyncEnumerable with synchronous foreach you get a compile error; the element arrives inside a Task. await foreach unwraps those Tasks automatically.

Exercise Consume with await foreach

Define static async IAsyncEnumerable<string> Words(). In its body write await Task.CompletedTask;, yield return "apple";, yield return "pear";, yield return "cherry";. Make Main a static async Task Main. Count with int count = 0; await foreach (string w in Words()) { count++; } and print with Console.WriteLine(count);.

Show example solution
In Words body write await Task.CompletedTask; yield return "apple"; yield return "pear"; yield return "cherry";. Make Main static async Task Main() and write int count = 0; await foreach (string w in Words()) { count++; } Console.WriteLine(count);
Example solution:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async IAsyncEnumerable<string> Words()
    {
        await Task.CompletedTask;
        yield return "apple";
        yield return "pear";
        yield return "cherry";
    }

    static async Task Main()
    {
        int count = 0;
        await foreach (string w in Words())
        {
            count++;
        }
        Console.WriteLine(count);
    }
}

Test yourself

  1. Complete await foreach

    static async Task Consume() { ____ foreach (int n in Stream()) { Console.WriteLine(n); } }
    Show answer
    static async Task Consume() { await foreach (int n in Stream()) { Console.WriteLine(n); } }
  2. Match foreach concepts

    foreach
    Consumes IEnumerable<T>
    await foreach
    Consumes IAsyncEnumerable<T>
    yield return
    Produces a stream element
    IAsyncEnumerable<T>
    Async stream type
  3. Which type does await foreach work on?

    • IEnumerable<T>
    • List<T>
    • Task<T>
    • IAsyncEnumerable<T>
    Show answer

    IAsyncEnumerable<T> — Correct. await foreach requires an IAsyncEnumerable<T>.

All lessons in Advanced