liveBook · Manning

IAsyncEnumerable<T>

As explained in C# Concurrency: Asynchronous and multithreaded programming

IAsyncEnumerable<T> is a .NET generic interface representing an object that asynchronously provides an enumerator for traversing a sequence of values.

IAsyncEnumerable<T> represents a sequence whose next value may require asynchronous work. It parallels IEnumerable<T>, but GetAsyncEnumerator returns an IAsyncEnumerator<T>; MoveNextAsync returns ValueTask<bool>, Current returns the value, and DisposeAsync releases the enumerator. The enumerator factory itself should return quickly, deferring lengthy initialization until MoveNextAsync. section 14.1

Consume an asynchronous sequence with await foreach. Conceptually, the compiler obtains an async enumerator, awaits MoveNextAsync on each iteration, reads Current, and asynchronously disposes the enumerator. This preserves the shape of ordinary foreach while allowing retrieval or generation of each item to suspend without blocking. section 14.1 section 14.8

Generate values asynchronously

private async IAsyncEnumerable<int> AsyncYieldDemo() { yield return 1; await Task.Delay(1000); yield return 2; } public async Task UseAsyncYieldDemo() { await foreach (var current in AsyncYieldDemo()) Console.WriteLine($"Got {current}"); } The compiler combines iterator and async transformations, producing IAsyncEnumerable<int> and IAsyncEnumerator<int> implementations. Each yield return advances a generated state machine; MoveNextAsync resumes the appropriate state and returns whether another value exists. section 14.2

Apply the interface with these practical patterns:

  • Pass cancellation with collection.WithCancellation(token), and mark an async iterator parameter with [EnumeratorCancellation]. The iterator must observe the token; passing it alone does not stop work. section 14.3 section 14.8
  • Use ToBlockingEnumerable only when non-asynchronous code has no alternative; it waits during each move and can lose asynchronous benefits or cause deadlocks. section 14.4
  • Add asynchronous LINQ operators through the System.Linq.Async NuGet library; the stated .NET 9 baseline does not provide built-in LINQ support for IAsyncEnumerable<T>. section 14.5

Build a consuming queue

A Channel<T>-backed async iterator can expose queue consumption through await foreach. Read with ReadAsync, catch ChannelClosedException, and use yield break when the channel completes; otherwise yield each received item. This produces a BlockingCollection<T>-like consuming API without blocking readers and supports asynchronous workers. section 14.7

Table 14.2 IEnumerator vs. IAsyncEnumerator (view table figure)

IEnumerator<T>

IAsyncEnumerator<T>

T Current {get;}

T Current {get;}

bool MoveNext()

ValueTask<bool> MoveNextAsync()

void Dispose()

ValueTask DisposeAsync()

Compare the synchronous and asynchronous enumerator contracts, including Current, MoveNext versus MoveNextAsync, and Dispose versus DisposeAsync. section 14.1

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Descends from interface contracts through compiler-generated iterator state machines, cancellation forwarding, blocking adaptation, and channel-backed queue construction.
Examples
Demonstrates delayed integer generation, cancellation, compiler expansion, and a Channel<T>-based consuming work queue.
What it assumes
Assumes familiarity with foreach, IEnumerable<T>, yield return, async/await, Task, and cancellation tokens.
What you can do after
Build asynchronous iterators and consuming queues, consume them with await foreach, and apply cancellation or compatibility adapters appropriately.
How it connects
Connects asynchronous iteration with IEnumerable<T>, IAsyncEnumerator<T>, async/await, yield return, CancellationToken, Channel<T>, and LINQ.

Also explained in

Compare how 2 books explain IAsyncEnumerable<T> →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C# Concurrency: Asynchronous and multithreaded programming. The section links point to the parts of the book it draws on.