EsoxSolutions.ObjectPool 3.0.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package EsoxSolutions.ObjectPool --version 3.0.2
                    
NuGet\Install-Package EsoxSolutions.ObjectPool -Version 3.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EsoxSolutions.ObjectPool" Version="3.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EsoxSolutions.ObjectPool" Version="3.0.2" />
                    
Directory.Packages.props
<PackageReference Include="EsoxSolutions.ObjectPool" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EsoxSolutions.ObjectPool --version 3.0.2
                    
#r "nuget: EsoxSolutions.ObjectPool, 3.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EsoxSolutions.ObjectPool@3.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EsoxSolutions.ObjectPool&version=3.0.2
                    
Install as a Cake Addin
#tool nuget:?package=EsoxSolutions.ObjectPool&version=3.0.2
                    
Install as a Cake Tool

EsoxSolutions.ObjectPool

Overview

EsoxSolutions.ObjectPool is a high-performance, thread-safe object pool for .NET 8+, .NET 9 and .NET 10. It supports automatic return of objects, async operations, performance metrics, and flexible configuration. Useful for pooling expensive resources like database connections, network clients, or reusable buffers.

What's New in Version 3.0

Performance & Reliability

  • 20-40% faster queryable pool operations with optimized TryGetObject(query) implementation
  • Critical bug fix: Eliminated race condition in DynamicObjectPool that could cause object creation failures under high concurrency
  • Thread-safe disposal: Improved PoolModel<T> disposal pattern using modern atomic operations

Modern C# 14 Features

  • Collection expressions: Cleaner initialization syntax ([1, 2, 3] instead of new List<int> { 1, 2, 3 })
  • Primary constructors: Simplified class declarations
  • ArgumentNullException.ThrowIfNull: Modern null checking patterns
  • Sealed classes: Better performance optimization opportunities

Technical Improvements

  • Optimized bulk operations: Uses PushRange for returning multiple objects efficiently
  • Early exit optimization: Query operations exit immediately when match found
  • Reduced allocations: Eliminated redundant snapshots and LINQ overhead
  • Better statistics: More accurate tracking under concurrent load

Quality Assurance

  • 100% test success rate: All 83 tests passing
  • Stress tested: Verified with 500 concurrent threads on 100 objects
  • Production ready: Comprehensive validation across .NET 8, 9, and 10

Features

  • Thread-safe object pooling with lock-free concurrent operations
  • Automatic return of objects via IDisposable pattern
  • Async support with GetObjectAsync, TryGetObjectAsync, timeout and cancellation
  • Queryable pools for finding objects matching predicates
  • Dynamic pools with factory methods for on-demand object creation
  • Health monitoring with real-time status and utilization metrics
  • Prometheus metrics exportable format with tags/labels
  • Pool configuration for max size, active objects, validation, and timeouts
  • Try methods* for non-throwing retrieval patterns
  • High-performance with O(1) get/return operations

Usage

PoolModel

A generic wrapper for pooled objects. Use Unwrap() to access the value.

var pool = new ObjectPool<int>([1, 2, 3]);  // Collection expression syntax
using (var model = pool.GetObject())
{
    var value = model.Unwrap();
    Console.WriteLine(value);
}

ObjectPool

Administers a fixed set of objects. Throws if pool is empty.

var initialObjects = new List<int> { 1, 2, 3 };
var pool = new ObjectPool<int>(initialObjects);
using (var model = pool.GetObject())
{
    Console.WriteLine(model.Unwrap());
}
Async Usage
using (var model = await pool.GetObjectAsync())
{
    Console.WriteLine(model.Unwrap());
}
Try Methods
if (pool.TryGetObject(out var model))
{
    using (model)
    {
        Console.WriteLine(model.Unwrap());
    }
}
Pool Configuration
var config = new PoolConfiguration {
    MaxPoolSize = 5,
    MaxActiveObjects = 3,
    ValidateOnReturn = true,
    ValidationFunction = obj => obj != null
};
var pool = new ObjectPool<int>(initialObjects, config);

QueryableObjectPool

Query for objects matching a predicate. Now 20-40% faster!

var pool = new QueryableObjectPool<int>([1, 2, 3]);
using (var model = pool.GetObject(x => x == 2))
{
    Console.WriteLine(model.Unwrap());
}

DynamicObjectPool

Creates objects on the fly using a factory method. Race condition fixed in v3.0!

var pool = new DynamicObjectPool<int>(() => 42);
using (var model = pool.GetObject())
{
    Console.WriteLine(model.Unwrap());
}

// With initial objects and factory for scaling
var pool = new DynamicObjectPool<Car>(
    () => new Car("Ford", "Dynamic"), 
    initialCars
);

Prometheus Exporter

Export pool metrics in Prometheus exposition format.

// Using interface default/extension
var prometheusText = ((IPoolMetrics)pool).ExportMetricsPrometheus();

// Or using concrete pool convenience method
var prometheusText = pool.ExportMetricsPrometheus();

// With optional tags as labels
var tags = new Dictionary<string, string> { 
    ["service"] = "order-service", 
    ["env"] = "prod" 
};
var prometheusTextWithLabels = pool.ExportMetricsPrometheus(tags);

The exporter emits HELP/TYPE lines and converts string metrics into *_info gauge metrics with a value label.

Health Monitoring & Metrics

var health = pool.GetHealthStatus();
Console.WriteLine($"Healthy: {health.IsHealthy}, Warnings: {health.WarningCount}");

var metrics = pool.ExportMetrics();
foreach (var kv in metrics)
    Console.WriteLine($"{kv.Key}: {kv.Value}");

Performance Characteristics

Operation Complexity Notes
GetObject() O(1) Constant time pop from concurrent stack
ReturnObject() O(1) Constant time push to concurrent stack
GetObject(query) O(n) worst case Optimized with early exit and bulk operations
TryGetObject() O(1) Non-throwing variant

Thread-Safety

All pool operations are thread-safe using lock-free ConcurrentStack<T> and ConcurrentDictionary<T, byte>:

  • Tested with 500 concurrent threads
  • Race condition free
  • No blocking locks in hot paths
  • Atomic operations for critical sections

Version History

3.0.0 (Current) - November 2025

  • Added support for .NET 10
  • 20-40% performance improvement for queryable pool operations
  • Critical fix: Eliminated race condition in DynamicObjectPool under high concurrency
  • Modern C# 14 patterns: collection expressions, primary constructors, sealed classes
  • 100% test pass rate (83/83 tests)
  • Added Prometheus metrics exporter
  • Production-ready certification

2.1.0

  • Added PoolConfiguration for flexible pool behavior
  • Improved health checks with utilization tracking
  • Fixed async disposal for queryable pool
  • Enhanced thread-safety for all pools

2.0.0

  • Async support with GetObjectAsync
  • Performance metrics and exporters
  • Try* methods for safe retrieval
  • Improved performance

1.1.5

  • Improved thread-safety
  • Dynamic pool throws if no match

1.1.3

  • Added DynamicObjectPool

1.1.2

  • Improved thread-safety

1.1.1

  • Added QueryableObjectPool

Production Use

This library is production-ready and suitable for:

  • High-traffic web applications (ASP.NET Core)
  • Microservices architectures
  • Cloud deployments (Azure, AWS, Kubernetes)
  • Enterprise systems
  • Real-time applications
  • Database connection pooling
  • Network client pooling

See DEPLOYMENT.md for production deployment guidance.

Contributing

Contributions are welcome! Please ensure:

  • All tests pass (dotnet test)
  • Code follows existing patterns
  • New features include tests
  • Documentation is updated

License

MIT License - See LICENSE.txt for details.


For bug reports or suggestions, contact info@esoxsolutions.nl


Disclaimer

Use of this software is at your own risk. The author(s) of EsoxSolutions.ObjectPool are not liable for any damages, losses, or other consequences resulting from the use, misuse, or inability to use this software.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version 3.0: Added support for .NET 10 and Prometheus