Wolfgang.Extensions.IAsyncEnumerable.Legacy
0.6.0
Prefix Reserved
dotnet add package Wolfgang.Extensions.IAsyncEnumerable.Legacy --version 0.6.0
NuGet\Install-Package Wolfgang.Extensions.IAsyncEnumerable.Legacy -Version 0.6.0
<PackageReference Include="Wolfgang.Extensions.IAsyncEnumerable.Legacy" Version="0.6.0" />
<PackageVersion Include="Wolfgang.Extensions.IAsyncEnumerable.Legacy" Version="0.6.0" />
<PackageReference Include="Wolfgang.Extensions.IAsyncEnumerable.Legacy" />
paket add Wolfgang.Extensions.IAsyncEnumerable.Legacy --version 0.6.0
#r "nuget: Wolfgang.Extensions.IAsyncEnumerable.Legacy, 0.6.0"
#:package Wolfgang.Extensions.IAsyncEnumerable.Legacy@0.6.0
#addin nuget:?package=Wolfgang.Extensions.IAsyncEnumerable.Legacy&version=0.6.0
#tool nuget:?package=Wolfgang.Extensions.IAsyncEnumerable.Legacy&version=0.6.0
Wolfgang.Extensions.IAsyncEnumerable
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.
📦 Installation
dotnet add package Wolfgang.Extensions.IAsyncEnumerable
NuGet Package: Wolfgang.Extensions.IAsyncEnumerable
On net462 / netstandard2.0, where System.Linq.AsyncEnumerable isn't available, add the companion legacy package for terminal operators (CountAsync, AnyAsync, FirstAsync, FirstOrDefaultAsync, ToListAsync):
dotnet add package Wolfgang.Extensions.IAsyncEnumerable.Legacy
NuGet Package: Wolfgang.Extensions.IAsyncEnumerable.Legacy
📄 License
This project is licensed under the MIT License. See the LICENSE file for details.
📚 Documentation
- 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
- Verify the build: docs/REPRODUCIBLE-BUILD.md
✨ Extension methods
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. |
Terminal operators (Wolfgang.Extensions.IAsyncEnumerable.Legacy, net462 / netstandard2.0 only)
These live on IAsyncEnumerableLegacyExtensions (same Wolfgang.Extensions.IAsyncEnumerable namespace, separate assembly). They exist only for TFMs where System.Linq.AsyncEnumerable isn't available — on net8.0+, use the BCL versions instead.
| Method | Purpose |
|---|---|
CountAsync<T>(source, ct) |
Counts the elements in the stream. |
AnyAsync<T>(source, ct) |
true if the stream yields any elements. Short-circuits on the first element. |
AnyAsync<T>(source, predicate, ct) |
true if any element satisfies the predicate. Short-circuits on the first match. |
FirstAsync<T>(source, ct) |
The first element; throws InvalidOperationException if the stream is empty. |
FirstOrDefaultAsync<T>(source, ct) |
The first element, or default(T) if the stream is empty. |
ToListAsync<T>(source, ct) |
Materializes the stream into a List<T>. |
🚀 Quick Start
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);
}
🎯 Supported Frameworks
Wolfgang.Extensions.IAsyncEnumerable targets:
- .NET Framework: 4.6.2
- .NET Standard: 2.0
- .NET: 8.0, 10.0
Wolfgang.Extensions.IAsyncEnumerable.Legacy targets:
- .NET Framework: 4.6.2
- .NET Standard: 2.0
See each package's NuGet page (main, Legacy) for the authoritative per-TFM compatibility matrix.
🔍 Code Quality
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.
🛠️ Building from Source
git clone https://github.com/Chris-Wolfgang/IAsyncEnumerable-Extensions.git
cd IAsyncEnumerable-Extensions
dotnet restore
dotnet build --configuration Release
dotnet test --configuration Release
SDK 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.
🙏 Acknowledgments
- 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
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.6.0 | 129 | 8/29/2026 |