0

0

C# 对象池化方法 C#如何使用Microsoft.Extensions.ObjectPool

幻夢星雲

幻夢星雲

发布时间:2026-02-04 09:16:03

|

486人浏览过

|

来源于php中文网

原创

ObjectPool需先配置策略再使用,通过DefaultObjectPoolProvider创建池,Get获取、Return归还对象;自定义PooledObjectPolicy可控制创建、验证与清理;注意MaximumRetained限制池大小防内存泄漏;池线程安全,但对象需确保线程安全且不可重复Return。

c# 对象池化方法 c#如何使用microsoft.extensions.objectpool

ObjectPool 基本用法:从创建到归还

直接用 ObjectPool 需要先配置一个池策略,不能 new 出来就用。最简路径是借助 DefaultObjectPoolProvider 创建带默认策略的池:

var provider = new DefaultObjectPoolProvider();
var pool = provider.Create(new DefaultPooledObjectPolicy());

获取对象用 Get(),用完必须调用 Return() —— 否则对象不会回到池里,等于白配:

  • var sb = pool.Get(); → 拿到实例(可能新建,也可能复用)
  • sb.Append("hello"); → 正常使用
  • pool.Return(sb); → 关键!不调用这句,下次 Get() 不会拿到它

自定义 PooledObjectPolicy:控制创建、验证和清理逻辑

默认策略只做 new T()obj?.Clear()(仅对 StringBuilder 等少数类型生效)。多数场景需要自己写策略,比如复用 MemoryStream 时得重置位置和长度:

public class MemoryStreamPolicy : IPooledObjectPolicy
{
    public MemoryStream Create() => new MemoryStream(1024);
    public bool Return(MemoryStream obj) => obj.Length == 0; // 可选校验
    public void Return(MemoryStream obj)
    {
        obj.Position = 0;
        obj.SetLength(0); // 清空内容,但保留缓冲区
    }
}

注意两点:

  • Return() 方法返回 bool 表示是否允许归还;返回 false 会被直接丢弃(如对象状态异常)
  • 不要在 Return() 里调用 Dispose() —— 池不负责释放资源,除非你明确在策略里处理

性能陷阱:池大小没限制,内存可能越攒越多

DefaultObjectPoolProvider 默认不限制池容量,空闲对象一直留着。高并发下若对象体积大(比如含大数组的类),容易吃光内存。

解决方法是传入 PoolingPolicyOptions 控制上限:

Flowstep
Flowstep

AI界面设计工具,通过对话几秒内创建UI设计图、线框图和流程图

下载
var options = new PoolingPolicyOptions
{
    MaximumRetained = 50, // 最多缓存 50 个空闲实例
};
var pool = provider.Create(new MyPolicy(), options);

另外,MaximumRetained 是 per-pool 的,不是全局总数。每个 Create() 调用都独立计数。

常见错误:把池当成单例或线程局部存储用

有人误以为池本身是线程安全的「容器」,然后在多个线程间共享同一个 ObjectPool 实例 —— 这没问题,ObjectPool 内部是线程安全的。

但错在:把池和它管理的对象混为一谈。典型错误包括:

  • 在线程 A 中 Get() 后,把对象传给线程 B 使用,再在线程 B 中 Return() —— 可以,但需确保对象本身线程安全(如 StringBuilder 不是)
  • 重复 Return() 同一个对象两次 —— 会触发内部断言失败或静默忽略,取决于策略实现
  • async 方法中 await 后才 Return(),中间被其他代码误用该对象

最稳妥的做法:Get 和 Return 尽量写在同一个作用域内,用 using 无法自动 Return,必须显式写。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

588

2023.08.10

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

344

2023.10.25

python中append的用法
python中append的用法

在Python中,append()是列表对象的一个方法,用于向列表末尾添加一个元素。想了解更多append的更多内容,可以阅读本专题下面的文章。

1074

2023.11.14

python中append的含义
python中append的含义

本专题整合了python中append的相关内容,阅读专题下面的文章了解更多详细内容。

176

2025.09.12

vsd文件打开方法
vsd文件打开方法

vsd文件打开方法有使用Microsoft Visio软件、使用Microsoft Visio查看器、转换为其他格式等。想了解更多vsd文件相关内容,可以阅读本专题下面的文章。

492

2023.10.30

全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

17

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

24

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

14

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

2

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 57.1万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号