.Net对象池扩展
什么是对象池?
对象池就是一种为对象提供可复用性能力的软件设计思路。简单而言就是将创建得对象放置到一个容器中(池),需要的时候从容器中获取,使用后归还到容器。保证对象可以被重复使用,进而节省频繁创建对象的性能开销。
.NET Core中的对象池
在.NET Core已经提供了对象池的实现,主要有三大对象:ObjectPoolProvider、ObjectPool
- ObjectPoolProvider:对象池提供器。用于构建对象池,指定对象池容量【默认电脑处理器数量的2倍】,默认创建DefaultObjectPool
,当对象实现IDisposable接口时创建DisposableObjectPool - ObjectPool
:对象池,提供对象的获取和归还。 - IPooledObjectPolicy
用于管理池对象的策略。可以指定池对象的创建和归还方式。
三个核心组件关系如下图:
示例:
TeacherObjectPoolPolicy
public class TeacherObjectPoolPolicy : IPooledObjectPolicy<Teacher>
{
public Teacher Create()
{
var id = Guid.NewGuid().ToString("N");
return new Teacher()
{
Id = id,
Name = "老师"
};
}
public bool Return(Teacher obj)
{
return true;
}
}
服务注册
var builder = WebApplication.CreateBuilder(args);
//对象池
builder.Services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
builder.Services.AddSingleton(serviceProvider =>
{
var objectPoolProvider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
return objectPoolProvider.Create(new TeacherObjectPoolPolicy());
});
var app = builder.Build();
使用
var policy = new TeacherObjectPoolPolicy();
//指定对象创建策略,对象池容量为2
var objectPool = new DefaultObjectPool<Teacher>(policy, 2);
var teacher1 = objectPool.Get();
var teacher2 = objectPool.Get();
Console.WriteLine(teacher1.Id);
Console.WriteLine(teacher2.Id);
Console.WriteLine(teacher1.Equals(teacher2));
objectPool.Return(teacher1);
var teacher3 = objectPool.Get();
Console.WriteLine(teacher3.Id);
//teacher3复用了teacher1对象
Console.WriteLine(teacher1.Equals(teacher3));
对象池扩展
简化对象池的适用,通过注入方式使用对象池,使用完成后自动释放归还
ObjectPoolManager
public interface IObjectPoolManager : IDisposable
{
T Get<T>() where T : class;
void Return<T>(T obj) where T : class;
}
public class ObjectPoolManager : IObjectPoolManager
{
private readonly IServiceProvider _services;
private readonly Dictionary<string, IAutoDisposableObjectPool> _dicObjectPool;
public ObjectPoolManager(IServiceProvider services)
{
_services = services;
_dicObjectPool = new Dictionary<string, IAutoDisposableObjectPool>();
}
public T Get<T>() where T : class
{
if (_dicObjectPool.TryGetValue(typeof(T).FullName, out IAutoDisposableObjectPool objectPool))
{
return objectPool.Get() as T;
}
objectPool = new AutoDisposableObjectPool<T>(_services.GetService(typeof(ObjectPool<T>)) as ObjectPool<T>);
_dicObjectPool[typeof(T).FullName] = objectPool;
return objectPool.Get() as T;
}
public void Return<T>(T obj) where T : class
{
if (!_dicObjectPool.TryGetValue(typeof(T).FullName, out IAutoDisposableObjectPool objectPool))
return;
objectPool.Return(obj);
}
public void Dispose()
{
foreach (var objectPool in _dicObjectPool)
{
objectPool.Value.Dispose();
}
}
private class AutoDisposableObjectPool<T> : IAutoDisposableObjectPool where T : class
{
private readonly ObjectPool<T> _objectPool;
private readonly IList<T> _items;
public AutoDisposableObjectPool(ObjectPool<T> objectPool)
{
_objectPool = objectPool;
_items = new List<T>();
}
public object Get()
{
var obj = _objectPool.Get();
_items.Add(obj);
return obj;
}
public void Return(object obj)
{
Return(obj as T);
}
private void Return(T obj)
{
_objectPool.Return(obj);
_items.Remove(obj);
}
public void Dispose()
{
var returnList = new List<T>(_items);
foreach (var item in returnList)
{
Return(item);
}
}
}
private interface IAutoDisposableObjectPool : IDisposable
{
object Get();
void Return(object obj);
}
服务注册
var builder = WebApplication.CreateBuilder(args);
//注册IObjectPoolManager为瞬时,请求结束自动归还对象
builder.Services.AddTransient<IObjectPoolManager, ObjectPoolManager>();
var app = builder.Build();
使用
public class ObjectPoolController : Controller
{
//构造函数注入IObjectPoolManager
private readonly IObjectPoolManager _objectPoolManager;
public ObjectPoolController(IObjectPoolManager objectPoolManager)
{
_objectPoolManager = objectPoolManager;
}
public async Task Test()
{
//多次获取没有归还返回,获取到的不同对象
for (int i = 0; i < 5; i++)
{
var techer = _objectPoolManager.Get<Teacher>();
Console.WriteLine(techer.Id);
}
Console.WriteLine("*******************");
//获取对象后手动归还,再次获取时同一对象
var teacher1 = _objectPoolManager.Get<Teacher>();
Console.WriteLine(teacher1.Id);
_objectPoolManager.Return(teacher1);
var teacher2 = _objectPoolManager.Get<Teacher>();
Console.WriteLine(teacher2.Id);
Console.WriteLine(teacher2.Equals(teacher2));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署