A collection of extension methods for IAsyncEnumerable<T> in .NET โ chunking, side-effect projection, eager iteration, and emptiness / quantifier predicates. Built async-first with strict analyzer enforcement and multi-TFM packaging.
dotnet add package Wolfgang.Extensions.IAsyncEnumerableNuGet Package: Wolfgang.Extensions.IAsyncEnumerable
This project is licensed under the MIT License. See the LICENSE file for details.
- GitHub Repository: https://github.com/Chris-Wolfgang/IAsyncEnumerable-Extensions
- API Documentation: https://Chris-Wolfgang.github.io/IAsyncEnumerable-Extensions/
- CHANGELOG: CHANGELOG.md
- Contributing Guide: CONTRIBUTING.md
- Formatting Guide: docs/README-FORMATTING.md
- DocFX Version Picker Troubleshooting: docs/DOCFX-VERSION-PICKER.md
- Release Workflow Setup: docs/RELEASE-WORKFLOW-SETUP.md
- Workflow Security: docs/WORKFLOW_SECURITY.md
All nine extensions live on IAsyncEnumerableExtensions (namespace Wolfgang.Extensions.IAsyncEnumerable). See the API documentation for signatures, parameter details, and per-method examples.
| Method | Purpose |
|---|---|
ChunkAsync<T>(source, maxChunkSize, ct) |
Splits the stream into fixed-size ICollection<T> batches. |
DoAsync<T>(source, Action<T>, ct) |
Side-effect projection โ runs a sync action per element; yields the originals unchanged. |
DoAsync<T>(source, Func<T, Task>, ct) |
Side-effect projection โ runs an async action per element; yields the originals unchanged. |
ForEachAsync<T>(source, Action<T>, ct) |
Eager iteration with a sync action โ terminal. |
ForEachAsync<T>(source, Func<T, Task>, ct) |
Eager iteration with an async action โ terminal. |
IsEmptyAsync<T>(source, ct) |
true if the stream yields zero elements. Short-circuits on the first element. |
IsNullOrEmptyAsync<T>(source?, ct) |
true if the stream is null or yields zero elements. Null-tolerant. |
NoneAsync<T>(source, ct) |
true if the stream yields zero elements (same shape as IsEmptyAsync, different naming). |
NoneAsync<T>(source, predicate, ct) |
true if no element satisfies the predicate. Short-circuits on the first match. |
using Wolfgang.Extensions.IAsyncEnumerable;
// Chunk an async stream into batches of up to 100, with logging side-effect
await foreach (var batch in source
.DoAsync(x => logger.LogInformation("Processing {Item}", x))
.ChunkAsync(maxChunkSize: 100, token: cancellationToken))
{
await ProcessBatchAsync(batch);
}net462, netstandard2.0, net8.0, net10.0 โ single NuGet package, picks the best fit at consume time.
This project enforces strict analyzer rules and async-first patterns via:
- Microsoft.CodeAnalysis.NetAnalyzers (built into the SDK) โ correctness + performance
- Roslynator.Analyzers โ refactoring + style
- AsyncFixer โ async/await anti-patterns
- Microsoft.VisualStudio.Threading.Analyzers โ thread-safety + async patterns
- Microsoft.CodeAnalysis.BannedApiAnalyzers โ banned synchronous APIs (see
BannedSymbols.txt) - Meziantou.Analyzer โ broad code-quality rules
- SonarAnalyzer.CSharp โ industry-standard analysis
- Microsoft.CodeAnalysis.PublicApiAnalyzers โ public-API surface change detection (see
src/.../PublicAPI.Shipped.txt)
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> is active for Release builds, so any analyzer warning blocks the release pipeline.
BannedSymbols.txt prohibits the usual sync-over-async traps: Task.Wait() / Task.Result, Thread.Sleep, sync file/stream I/O, Parallel.For/ForEach, WebClient, BinaryFormatter.
git clone https://github.com/Chris-Wolfgang/IAsyncEnumerable-Extensions.git
cd IAsyncEnumerable-Extensions
dotnet restore
dotnet build --configuration Release
dotnet test --configuration ReleaseSDK requirement: the version installed by .github/workflows/pr.yaml (currently .NET 10 + side-by-side SDKs for the older TFMs). See docs/README-FORMATTING.md for the source-formatting workflow.
- Microsoft.Bcl.AsyncInterfaces โ
IAsyncEnumerable<T>backport fornet462/netstandard2.0 - The analyzer-package authors above
- The .NET team for
IAsyncEnumerable<T>and the async-stream language support that made this library a one-file project