Object Pool – Avoid expensive acquisition and release of resources by recycling objects that are no longer in use.
From Design Patterns – Creational Patterns
Structure

Applicability
Object pooling can provide a significant performance. Most situations use the object pooling when the class instance initializing cost is high or uses system resource is too more, the class instance reuses in any one time.
In recent years, most people use object pooling to do the managed thread pools based on the class library products, the win form products, web form products, the WCF, etc. Few people will use the managed thread pools on the ASP.NET Core web application, which is made by Microsoft.Exetension.ObjectPool packages. It supports a group of objects in memory for reuse rather than allowing the objects to be garbage collected. The developers want to do the object pooling because they want to manage below:
- Expensive to allocate/initialize.
- Represent some limited resource.
- Used predictably and frequently.
From Microsoft’s article – Object reuse with ObjectPool in ASP.NET Core
It looks like the right concepts, but one thing must remember the object pooling doesn’t always improve performance.
- Unless the initialization cost of an object is high, it’s usually slower to get the object from the pool.
- Objects managed by the pool aren’t de-allocated until the pool is de-allocated.
From Microsoft’s article – Object reuse with ObjectPool in ASP.NET Core
It can quickly know the using object pooling only can after collection performance data in realistic situation for the app or library.
Pros and Cons
PROS
- Expensive to allocate/initialize.
- Represent some limited resource.
- Used predictably and frequently.
CONS
- Waiting for a particular object to be released, then object pooling instantiates new object.
How to Implement
Implement the object pooling has three way below:
- Instantiating a pool.
- Registering a pool in dependency injection as an instance.
- Registering the ObjectPoolProvider<> in dependency injection and using it as a factory
#1 Basic Sample
using Microsoft.Extensions.ObjectPool;
...
static void Main()
{
ObjectPool<Demo> pool = new ObjectPooling<Demo>().PoolInstance();
var item1 = pool.Get();
pool.Return(item1);
var item2 = pool.Get();
Console.WriteLine($"{item1.Guid_ID}--{item1.Id}-{item1.Name}-{item1.CreateTime}");
Console.WriteLine($"{item2.Guid_ID}--{item2.Id}-{item2.Name}-{item2.CreateTime}");
Console.WriteLine(item1 == item2);
var item3 = pool.Get();
Console.WriteLine($"{item3.Guid_ID}--{item3.Id}-{item3.Name}-{item3.CreateTime}");
Console.WriteLine(item3 == item2);
}
public class Demo
{
public int Id { get; set; } = 0;
public string Name { get; set; } = string.Empty;
public DateTime CreateTime { get; set; }
public Guid Guid_ID { get; set; }
}
public class DemoObjectPoolingPolicy<T> : IPooledObjectPolicy<T> where T : class
{
public bool Return(T obj) => true;
T IPooledObjectPolicy<T>.Create()
{
return new Demo { Guid_ID = Guid.NewGuid(), Id = 1, Name = "catcher", CreateTime = DateTime.Now } as T;
}
}
public class ObjectPooling<T> where T : class
{
private DefaultObjectPoolProvider defaultObjectPoolProvider;
public ObjectPooling()
{
this.defaultObjectPoolProvider = new DefaultObjectPoolProvider();
}
public ObjectPool<T> PoolInstance()
{
var policy = new DemoObjectPoolingPolicy<T>();
return this.defaultObjectPoolProvider.Create<T>(policy);
}
}
#2 Web Application Project
Step 1 Adds ObjectPoolProvider to the dependency injection container in the startup file.
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Text;
...
services.TryAddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
Step 2 Adds and configures ObjectPool<StringBuilder> to the dependency injection contrainer.
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Text;
services.TryAddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
services.TryAddSingleton<ObjectPool<StringBuilder>>(serviceProvider => {
var provider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
var policy = new StringBuilderPooledObjectPolicy();
return provider.Create(policy);
});
Step 3 Adds the middleware layer under the web project. The middleware layer’s class file name sets “ObjectPoolingMiddleware.”

Note: If you want to see full of source code in the ObjectPoolingMiddleware class file, please follow my GitHub repository.
Add the ObjectPoolingMiddleware class file in the “Startup” file.
//Test using /?Id=123&day=28&month=9
app.UseMiddleware<ObjectPoolingMiddleware>();
Reference
- Source Making – Object Pool Design Pattern
- Microsoft Docs – The managed thread pool
- Microsoft Docs – Object reuse with ObjectPool in ASP.NET Core
- Detailed Explanation of Object Pool’s Various Usages in.NET Core