> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C# Await Foreach Loop

The `await foreach` statement is an asynchronous iteration construct introduced in C# 8.0 that allows developers to consume data streams asynchronously. It sequentially processes elements as they become available, yielding the thread execution context back to the caller between iterations rather than blocking while waiting for the next element to materialize.

```csharp theme={"dark"}
await foreach (T variable in asyncEnumerableExpression)
{
    // Execution body
}
```

## Architectural Mechanics

Standard synchronous `foreach` loops operate on `IEnumerable<T>` and block the executing thread during `IEnumerator<T>.MoveNext()`. Conversely, `await foreach` operates on asynchronous streams. The critical distinction lies in the enumerator: `MoveNextAsync()` returns a `ValueTask<bool>` instead of a synchronous `bool`.

When the compiler encounters an `await foreach` loop, it lowers the syntax into a state machine that handles asynchronous advancement and, if applicable, asynchronous disposal.

The conceptual compiler expansion of an `await foreach` loop looks like this:

```csharp theme={"dark"}
var enumerator = asyncEnumerableExpression.GetAsyncEnumerator();
try
{
    // Awaits the asynchronous retrieval of the next element
    while (await enumerator.MoveNextAsync()) 
    {
        T variable = enumerator.Current;
        // Execution body
    }
}
finally
{
    // Asynchronously disposes of resources only if the enumerator supports it
    if (enumerator is IAsyncDisposable asyncDisposable)
    {
        await asyncDisposable.DisposeAsync(); 
    }
}
```

## Cancellation Integration

Because asynchronous operations often require cancellation mechanisms, `await foreach` supports `CancellationToken` injection. However, you cannot pass the token directly into the loop syntax. Instead, you must use the `WithCancellation()` extension method provided by the `System.Threading.Tasks` namespace.

This method binds the `CancellationToken` to the underlying enumerator, ensuring that the token is passed to the producer's asynchronous state machine.

```csharp theme={"dark"}
CancellationTokenSource cts = new CancellationTokenSource();

await foreach (var item in asyncEnumerableExpression.WithCancellation(cts.Token))
{
    // Execution body
}
```

## Context Synchronization

By default, `await foreach` captures the current `SynchronizationContext` (if one exists) and attempts to marshal the continuation back to that context after every awaited `MoveNextAsync()` call. To prevent this overhead and force continuations to execute on a thread pool thread, you must append `ConfigureAwait(false)`.

When combining `ConfigureAwait` and `WithCancellation`, the order of method chaining does not matter, but both must be applied directly to the enumerable expression.

```csharp theme={"dark"}
await foreach (var item in asyncEnumerableExpression
    .WithCancellation(cancellationToken)
    .ConfigureAwait(false))
{
    // Execution body
}
```

## Interface and Pattern Requirements

For a type to be compatible with `await foreach`, it must satisfy one of the following conditions:

1. Implement the `IAsyncEnumerable<T>` interface.
2. Satisfy the asynchronous enumerable pattern (duck typing) by exposing a `GetAsyncEnumerator()` method that is **callable with no arguments** (meaning it can be parameterless, or all of its parameters can be optional). This method can be implemented as an instance method or as an **extension method**, which allows developers to add `await foreach` support to external or third-party types.

The enumerator type returned by `GetAsyncEnumerator()` must satisfy the asynchronous enumerator pattern by providing:

* A `MoveNextAsync()` method that returns a `ValueTask<bool>` (or any awaitable type yielding a `bool`).
* A `Current` property exposing the current element.

Implementing `DisposeAsync()` (or the `IAsyncDisposable` interface) on the enumerator is entirely **optional**. If the disposal method is absent, the compiler simply skips the disposal step during the lowering process without throwing an error.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
