千家信息网

.NET Core中对象池Object Pool的使用方法是什么

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要讲解了".NET Core中对象池Object Pool的使用方法是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习".NET Core中
千家信息网最后更新 2025年11月07日.NET Core中对象池Object Pool的使用方法是什么

这篇文章主要讲解了".NET Core中对象池Object Pool的使用方法是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习".NET Core中对象池Object Pool的使用方法是什么"吧!

一、什么是对象池

对象池简单来说就是一种为对象提供可复用能力的软件设计思路。我们常说有借有还,再借不难,而对象池就是通过借和还这样两个动作来保证对象可以被重复使用,从而节省频繁创建对象的性能开销。对象池最常用的场景是游戏设计,因为在游戏中大量存在着可复用的对象,源源不断的子弹出现并不是循环再生的。在数据库中存在着被称为连接池的东西,每当出现数据库无法连接的情况时,经验丰富的开发人员往往会先检查连接池是否满了,这其实就是对象池模式在特定领域的具体实现。因此对象池本质上就是负责一组对象创建和销毁的容器。 对象池最大的优势是可以自主地管理池子内的每个对象,决定它们是需要被回收还是可以重复使用。我们都知道创建一个新对象需要消耗一定的系统资源,一旦这些对象可以重复地使用就可以节省系统资源开销,这对提高系统性能会非常有帮助。下面的代码实微软官方文档实现的一个简单的对象池:


public class ObjectPool : IObjectPool{        private Func _instanceFactory;        private ConcurrentBag _instanceItems;        public ObjectPool(Func instanceFactory)        {                _instanceFactory = instanceFactory ??                 throw new ArgumentNullException(nameof(instanceFactory));                _instanceItems = new ConcurrentBag();        }        public T Get()        {                T item;                if (_instanceItems.TryTake(out item)) return item;                return _instanceFactory();        }        public void Return(T item)        {                _instanceItems.Add(item);        }}

二、.NET Core 中的对象池

.NET Core 中微软已经为我们提供了对象池的实现,即Microsoft.Extensions.ObjectPool。它主要提供了三个核心的组件,分别是ObjectPoolObjectPoolProviderIPooledObjectPolicyObjectPool是一个抽象类,对外提供了Get和Return两个方法,这就是所谓的有借有还。ObjectPoolProvider同样是一个抽象类,它的职责就是创建ObjectPool,它提供了两个Create方法,两者的区别是无参数版本本质上使用的是DefaultPooledObjectPolicy。它和DefaultObjectPool、DefaultObjectPoolProvider都是微软提供的默认实现,IPooledObjectPolicy可以为不同的对象池定义不同的策略,来决定对象如何借、是否可以还。DefaultObjectPool内部使用ObjectWrapper[]来管理对象,ObjectWrapper[]的大小等于 maximumRetained-1,默认情况下maximumRetained等于Environment.ProcessorCount * 2,这里主要用到了Interlocked.CompareExchange()方法,

具体代码如下:

public override T Get(){  var item = _firstItem;  if (item == null || Interlocked.CompareExchange(ref _firstItem, null, item) != item)  {    var items = _items;    for (var i = 0; i < items.Length; i++)    {      item = items[i].Element;      if (item != null && Interlocked.CompareExchange(ref items[i].Element, null, item) == item)      {        return item;      }    }    item = Create();  }  return item;}// Non-inline to improve its code quality as uncommon path[MethodImpl(MethodImplOptions.NoInlining)]private T Create() => _fastPolicy?.Create() ?? _policy.Create();public override void Return(T obj){  if (_isDefaultPolicy || (_fastPolicy?.Return(obj) ?? _policy.Return(obj)))  {    if (_firstItem != null || Interlocked.CompareExchange(ref _firstItem, obj, null) != null)    {      var items = _items;      for (var i = 0; i < items.Length && Interlocked.CompareExchange(ref items[i].Element, obj, null) != null; ++i)      {      }    }  }}

这里用到Interlocked.CompareExchange()方法,Get()方法将items[i].Elementnull进行交换,将指定元素设为 null 并返回原始值。Return()方法将items[i].Element和obj交换后的值不为 null,表示指定元素已经归还,这个方法只有在第一个参数和第三个参数相等时才会发生交换。

说了这么多,我们来看一下对象池具体的用法:

var service = new ServiceCollection();//使用DefaultObjectPoolProviderservice.AddSingleton();//使用默认策略service.AddSingleton>(serviceProvider =>{  var objectPoolProvider = serviceProvider.GetRequiredService();  return objectPoolProvider.Create();});//使用自定义策略service.AddSingleton>(serviceProvider =>{  var objectPoolProvider = serviceProvider.GetRequiredService();  return objectPoolProvider.Create(new FooObjectPoolPolicy());});var serviceProvider = _service.BuildServiceProvider();var objectPool = _serviceProvider.GetService>();//有借有还,两次是同一个对象var item1 = objectPool.Get();objectPool.Return(item1);var item2 = objectPool.Get();Assert.AreEqual(item1, item2);//true//有借无还,两次是不同的对象var item3 = objectPool.Get();var item4 = objectPool.Get();Assert.AreEqual(item3, item4);//false

上面的代码中Foo和FooObjectPoolPolicy是两个工具类:

public class Foo{  public string Id { get; set; }  public DateTime? CreatedAt { get; set; }  public string CreatedBy { get; set; }}public class FooObjectPoolPolicy : IPooledObjectPolicy{  public Foo Create()  {    return new Foo()    {      Id = Guid.NewGuid().ToString("N"),      CreatedAt = DateTime.Now,      CreatedBy = "zs"    };  }  public bool Return(Foo obj)  {    return true;  }}

TIP:当你需要控制对象池内的对象如何被创建的时候,你可以考虑实现自定义的IPooledObjectPolicy,反之DefaultPooledObjectPolicy实现完全可以满足你的使用。

感谢各位的阅读,以上就是".NET Core中对象池Object Pool的使用方法是什么"的内容了,经过本文的学习后,相信大家对.NET Core中对象池Object Pool的使用方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

对象 方法 就是 使用方法 两个 不同 有借有还 代码 参数 情况 策略 系统 微软 学习 三个 元素 内容 开销 思路 性能 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 虹口区智能网络技术开发价目表 客户端和服务器不支持ssl怎么处理 网络安全建设有哪些 武汉 网络安全人才会议 csgo有两种服务器吗 联想服务器提示风扇错误 规划设计网络安全结构 嘉源深圳网络技术有限公司 倩女ol有外国服务器吗 怎么给服务器增加盘 幻塔为什么登录过的服务器要排队 2018年网络安全单选 crm软件开发 彦夏 深圳软件开发视频 出租屋数据库课程设计 某网站的用户数据库泄露影响 亚圣科技互联网规划师 网络安全大赛主机渗透 百姓家网络技术有限公司 安全wifi服务器地址 网络安全软件后门 计算机网络技术什么的 一台服务器有几个光纤接口 软件开发工作量核定和收入 什么是数据库实现阶段的主要任务 如何清除软件用户数据库 定制软件开发的分类 帆软抓数据库信息 计算机三级网络技术40套 嘉兴可视化智慧工厂软件开发
0