Wolfgang.Extensions.IAsyncEnumerable
High-performance, production-grade extension methods for IAsyncEnumerable<T> with comprehensive test coverage and strict code quality enforcement.
📦 Installation
dotnet add package Wolfgang.Extensions.IAsyncEnumerable
NuGet Package: Available on NuGet.org
🚀 Quick Start
using Wolfgang.Extensions.IAsyncEnumerable;
// Chunk an async stream into batches
await foreach (var chunk in asyncStream.ChunkAsync(maxChunkSize: 100, token: cancellationToken))
{
// Process each chunk (ICollection<T>)
await ProcessBatchAsync(chunk);
}
✨ Features
Current Extension Methods
ChunkAsync<T>
Splits an IAsyncEnumerable<T> into fixed-size chunks for batch processing.
public static async IAsyncEnumerable<ICollection<T>> ChunkAsync<T>(
this IAsyncEnumerable<T> source,
int maxChunkSize,
CancellationToken token = default)
Parameters:
source- The source async enumerable to chunkmaxChunkSize- Maximum size of each chunk (must be > 0)token- Optional cancellation token
Returns: An async enumerable of collections, where each collection contains up to maxChunkSize elements.
Example:
var numbers = GetAsyncNumbers(); // IAsyncEnumerable<int>
await foreach (var batch in numbers.ChunkAsync(50))
{
Console.WriteLine($"Processing batch of {batch.Count} items");
// Last batch may be smaller than 50
}
DoAsync<T> (Synchronous action)
Executes a synchronous side-effect action on each element without transforming the elements. The original items are yielded unchanged.
public static async IAsyncEnumerable<T> DoAsync<T>(
this IAsyncEnumerable<T> source,
Action<T> action,
CancellationToken token = default)
Parameters:
source- The source async enumerableaction- The synchronous action to execute on each elementtoken- Optional cancellation token
Returns: An async enumerable that yields the original elements after executing the action.
Example:
var numbers = GetAsyncNumbers(); // IAsyncEnumerable<int>
await foreach (var item in numbers.DoAsync(x => Console.WriteLine($"Processing: {x}")))
{
// item is unchanged — DoAsync is a pass-through
}
DoAsync<T> (Asynchronous action)
Executes an asynchronous side-effect action on each element without transforming the elements.
public static async IAsyncEnumerable<T> DoAsync<T>(
this IAsyncEnumerable<T> source,
Func<T, Task> action,
CancellationToken token = default)
Parameters:
source- The source async enumerableaction- The asynchronous action to execute on each elementtoken- Optional cancellation token
Returns: An async enumerable that yields the original elements after executing the action.
Example:
// Chain DoAsync with other extensions for logging/metrics in a pipeline
await foreach (var batch in source
.DoAsync(async x => await logger.LogAsync($"Processing: {x}"))
.ChunkAsync(100))
{
await ProcessBatchAsync(batch);
}
🎯 Target Frameworks
This library supports multiple .NET versions:
- .NET Framework 4.6.2 (
net462) - .NET Standard 2.0 (
netstandard2.0) - .NET 8.0 (
net8.0) - .NET 10.0 (
net10.0)
🔍 Code Quality & Static Analysis
This project enforces strict code quality standards through 7 specialized analyzers and custom async-first rules:
Analyzers in Use
- Microsoft.CodeAnalysis.NetAnalyzers - Built-in .NET analyzers for correctness and performance
- Roslynator.Analyzers - Advanced refactoring and code quality rules
- AsyncFixer - Async/await best practices and anti-pattern detection
- Microsoft.VisualStudio.Threading.Analyzers - Thread safety and async patterns
- Microsoft.CodeAnalysis.BannedApiAnalyzers - Prevents usage of banned synchronous APIs
- Meziantou.Analyzer - Comprehensive code quality rules
- SonarAnalyzer.CSharp - Industry-standard code analysis
Async-First Enforcement
This library uses BannedSymbols.txt to prohibit synchronous APIs and enforce async-first patterns:
Blocked APIs Include:
- ❌
Task.Wait(),Task.Result- Useawaitinstead - ❌
Thread.Sleep()- Useawait Task.Delay()instead - ❌ Synchronous file I/O (
File.ReadAllText) - Use async versions - ❌ Synchronous stream operations - Use
ReadAsync(),WriteAsync() - ❌
Parallel.For/ForEach- UseTask.WhenAll()orParallel.ForEachAsync() - ❌ Obsolete APIs (
WebClient,BinaryFormatter)
Why? To ensure all code is truly async and non-blocking for optimal performance in async contexts.
🛠️ Building from Source
Prerequisites
- .NET 10.0 SDK or later
- Optional: PowerShell Core for formatting scripts
Build Steps
# Clone the repository
git clone https://github.com/Chris-Wolfgang/IAsyncEnumerable-Extensions.git
cd IAsyncEnumerable-Extensions
# Restore dependencies
dotnet restore
# Build the solution
dotnet build --configuration Release
# Run tests
dotnet test --configuration Release
# Run code formatting (PowerShell Core)
pwsh ./format.ps1
Code Formatting
This project uses .editorconfig and dotnet format:
# Format code
dotnet format
# Verify formatting (as CI does)
dotnet format --verify-no-changes
See README-FORMATTING.md for detailed formatting guidelines.
Building Documentation
This project uses DocFX to generate API documentation:
# Install DocFX (one-time setup)
dotnet tool install -g docfx
# Generate API metadata and build documentation
cd docfx_project
docfx metadata # Extract API metadata from source code
docfx build # Build HTML documentation
# Documentation is generated in the docs/ folder at the repository root
The documentation is automatically built and deployed to GitHub Pages when changes are pushed to the main branch.
Local Preview:
# Serve documentation locally (with live reload)
cd docfx_project
docfx build --serve
# Open http://localhost:8080 in your browser
Documentation Structure:
docfx_project/- DocFX configuration and source filesdocs/- Generated HTML documentation (published to GitHub Pages)docfx_project/index.md- Main landing page contentdocfx_project/docs/- Additional documentation articlesdocfx_project/api/- Auto-generated API reference YAML files
🤝 Contributing
Contributions are welcome! Please see CONTRIBUTING.md for:
- Code quality standards
- Build and test instructions
- Pull request guidelines
- Analyzer configuration details
📄 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: Latest
- Formatting Guide: README-FORMATTING.md
- Contributing Guide: CONTRIBUTING.md
🙏 Acknowledgments
Built with:
- Microsoft.Bcl.AsyncInterfaces for backward compatibility
- Comprehensive analyzer packages for code quality enforcement
- .NET async/await patterns for optimal performance