# Broadcast a stream to independent readers

TeeForge 0.1.0 · .NET 10 · **released**

Start all consumers concurrently so slow-reader backpressure can make progress.

Run from the repository root:

```text
dotnet run --project samples/TeeForge.Quickstart -c Release -- broadcast
```

The runner calls this example's RunAsync method with a cancellation token. The
example checks its result and throws on failure. Source: samples/TeeForge.Quickstart/BroadcastExample.cs.

<!-- Generated by eng/update-docs.ps1. Edit the C# source, then regenerate. -->
```csharp
using TeeForge.Broadcasting;

namespace TeeForge.Quickstart;

internal static class BroadcastExample
{
    public static async Task RunAsync(CancellationToken cancellationToken)
    {
        // Exceed the buffer threshold so this example exercises slow-reader backpressure.
        byte[] payload = Enumerable.Range(0, 100_003).Select(value => (byte)value).ToArray();
        await using var source = new MemoryStream(payload);
        await using var first = new MemoryStream();
        await using var second = new MemoryStream();
        await using var broadcast = new BroadcastStream(source, readerCount: 2,
            new BroadcastStreamOptions(leaveOpen: true), cancellationToken);

        // Start every consumer before awaiting completion. An idle reader can block the producer.
        Task firstCopy = broadcast.Readers[0].CopyToAsync(first, cancellationToken);
        Task secondCopy = broadcast.Readers[1].CopyToAsync(second, cancellationToken);
        await Task.WhenAll(firstCopy, secondCopy);
        await broadcast.Completion;

        if (!first.ToArray().AsSpan().SequenceEqual(payload) ||
            !second.ToArray().AsSpan().SequenceEqual(payload))
        {
            throw new InvalidOperationException("Every independent reader must receive the entire sequence.");
        }
    }
}
```

[Usage guide](../agent-guide.md) · [All recipes](index.md)
