Back to results for “Asynchronous Programming”
C# › Asynchronous Programming

How do IAsyncEnumerable<T> and 'await foreach' let you consume an asynchronous stream of values one at a time?

Advanced

Answer

IAsyncEnumerable<T>, produced by an async iterator method using 'yield return', represents a sequence where EACH element may require an asynchronous operation to produce — 'await foreach' consumes this sequence, awaiting each MoveNextAsync() call, letting you process large or slow-arriving data streams (like paginated API results) without loading everything into memory upfront.
async IAsyncEnumerable<string> FetchPagesAsync(string url) {
  string? next = url;
  while (next != null) {
    var (items, nextUrl) = await FetchPageAsync(next);
    foreach (var item in items) yield return item;
    next = nextUrl;
  }
}

await foreach (var item in FetchPagesAsync(startUrl)) {
  Console.WriteLine(item);
}
Real-world example Streaming and processing paginated API results or database query results one page at a time without holding the entire dataset in memory.

Common follow-ups: Can an IAsyncEnumerable<T> sequence also accept a CancellationToken to support cancellation mid-stream?