NPipeline Analyzers is a comprehensive Roslyn analyzer package designed to help developers build efficient, robust, and performant data processing pipelines
using the NPipeline framework. This package provides real-time diagnostics and code fixes to detect and resolve common pipeline configuration issues,
performance bottlenecks, and anti-patterns.
About NPipeline
NPipeline is a high-performance, extensible data processing framework for .NET that enables developers to build scalable and efficient pipeline-based
applications. It provides a rich set of components for data transformation, aggregation, branching, and parallel processing, with built-in support for
resilience patterns and error handling.
Installation
dotnet add package NPipeline.Analyzers
Requirements
.NET Standard 2.0 compatible IDE
Visual Studio 2017+ or JetBrains Rider or VS Code with C# extension
C# 8.0 or later for full feature support
Features
Real-time Diagnostics: Detects common pipeline configuration issues and performance anti-patterns as you code
Automated Code Fixes: Provides one-click fixes for most detected issues
Performance Optimization: Identifies bottlenecks in hot paths and suggests optimizations
Resilience Patterns: Ensures proper error handling and cancellation token usage
Configuration Validation: Validates pipeline configuration parameters for optimal performance
Async/Await Best Practices: Enforces proper async patterns in pipeline implementations
Supported Analyzers (18)
The package includes 18 comprehensive analyzers covering different aspects of pipeline development:
Performance Analyzers
AnonymousObjectAllocationAnalyzer - Detects anonymous object allocations in hot paths that can cause GC pressure
InefficientStringOperationsAnalyzer - Identifies inefficient string concatenation and manipulation in performance-critical code
LinqInHotPathsAnalyzer - Detects LINQ operations in high-frequency execution paths that cause unnecessary allocations
ValueTaskOptimizationAnalyzer - Identifies opportunities to optimize synchronous completions with ValueTask
Configuration Analyzers
- Detects mismatched batch size and timeout configurations
BatchingConfigurationMismatchAnalyzer
InappropriateParallelismConfigurationAnalyzer - Identifies inappropriate parallelism settings that can cause resource contention
TimeoutConfigurationAnalyzer - Detects timeout values that are too short or too long for the workload type
UnboundedMaterializationConfigurationAnalyzer - Identifies potential memory leaks from unbounded materialization
Async/Cancellation Analyzers
BlockingAsyncOperationAnalyzer - Detects blocking calls on async operations that can cause deadlocks
CancellationTokenRespectAnalyzer - Ensures proper cancellation token propagation and usage
SinkNodeInputConsumptionCodeFixProvider - Adds proper async enumeration for input consumption
SourceNodeStreamingCodeFixProvider - Converts to streaming patterns for source nodes
SynchronousOverAsyncCodeFixProvider - Replaces sync-over-async patterns with proper async
TimeoutConfigurationCodeFixProvider - Optimizes timeout values based on workload characteristics
UnboundedMaterializationConfigurationCodeFixProvider - Adds bounds to materialization operations
ValueTaskOptimizationCodeFixProvider - Converts Task.FromResult patterns to ValueTask
Example Diagnostics
Performance Issues
// Inefficient string concatenation in a hot path
public string ProcessItem(Item item)
{
string result = "Processing: " + item.Name + " at " + DateTime.Now;
return result;
}
// Diagnostic: NPIPE001: Use StringBuilder or string interpolation for efficient string concatenation
// LINQ in hot path
public List<Result> TransformItems(List<Item> items)
{
return items.Where(x => x.IsValid)
.Select(x => new Result(x))
.ToList();
}
// Diagnostic: NPIPE002: Avoid LINQ operations in hot paths
Configuration Issues
// Inappropriate parallelism for I/O-bound work
var strategy = new ParallelExecutionStrategy
{
DegreeOfParallelism = Environment.ProcessorCount
};
// Diagnostic: NPIPE003: High parallelism for I/O-bound work may cause resource contention
// Timeout too short for complex processing
var resilientStrategy = new ResilientExecutionStrategy
{
Timeout = TimeSpan.FromMilliseconds(100)
};
// Diagnostic: NPIPE004: Timeout may be too short for the workload type
Async/Await Issues
// Blocking on async code
public void ProcessData()
{
var result = GetDataAsync().Result;
}
// Diagnostic: NPIPE005: Avoid blocking on async operations
// Not respecting cancellation token
public async Task ProcessAsync(CancellationToken cancellationToken)
{
await ProcessItemAsync(); // Missing cancellationToken parameter
}
// Diagnostic: NPIPE006: Async method should respect cancellation token
Troubleshooting
Analyzers Not Running
Ensure the package is installed in the project you're working on
Restart Visual Studio after installing the package
Check that analyzers are enabled in your project settings:
The analyzers integrate seamlessly with your build process:
# Build with warnings as errors
dotnet build --warnaserror
# Run specific analyzers
dotnet build -p:RunAnalyzers=true -p:AnalyzerPlugins=NPipeline.Analyzers
Contributing
We welcome contributions to the NPipeline Analyzers package! Here's how you can help:
Reporting Issues
Check existing issues to avoid duplicates
Provide a minimal reproduction when reporting bugs
Include diagnostic IDs and code examples when possible
Describe the expected vs. actual behavior
Submitting Pull Requests
Fork the repository and create a feature branch
Follow the existing code style and patterns
Add tests for new analyzers or fixes
Update documentation for any new features
Ensure all tests pass before submitting
Development Setup
# Clone the repository
git clone https://github.com/npipeline/NPipeline.git
cd NPipeline
# Build the solution
dotnet build
# Run tests
dotnet test
# Pack the analyzer package
dotnet pack src/NPipeline.Analyzers.Package
Adding New Analyzers
When adding a new analyzer:
Inherit from DiagnosticAnalyzer and use the [DiagnosticAnalyzer] attribute
Follow the naming convention: [Name]Analyzer.cs
Provide clear diagnostic messages with actionable advice
Implement a corresponding code fix provider when possible
Add comprehensive tests covering various scenarios
Update the documentation with the new analyzer's purpose and usage