ArrayPoolWrapper简洁、安全的ArrayPool

简介: 本文针对.NET中ArrayPool使用繁琐、易出错的问题,提出轻量级封装方案ArrayPoolWrapper。它通过using语法自动管理租借/归还,避免样板代码;支持Count、Values(Span切片)、RemoveLastOne等便捷API,提升开发效率与代码可读性。(239字)

通过.NET中的 ArrayPool 我们可以实现对T[]类型的池化,避免频繁的分配内存和GC,以提升性能。鉴于已有不少博客介绍ArrayPool的具体原理,本文不会涉及其实现细节。本文聚焦使用中的痛点,并提供简洁的封装方案以提升ArrarPool使用的便捷性。

ArrayPool本身的使用方式比较简单:

using System.Buffers;
var pool = ArrayPool<int>.Shared.Rent(4);
// 其他逻辑
ArrayPool<int>.Shared.Return(pool);

为了确保在发生异常时能够释放资源,通常需要写成如下形式的样板代码:

int[] pool = null!;
try
{
    pool = ArrayPool<int>.Shared.Rent(4);
    // 其他逻辑
}
finally
{
    if (pool != null)
    {
        ArrayPool<int>.Shared.Return(pool);
    }
}

以上写法会是我们的代码中充斥大量的样板代码和大量的嵌套,影响代码后续的可读性和可维护性。

接下来我们在原ArrayPool的基础上稍加封装,以实现简洁、安全的使用ArrayPool的目标,封装后的使用只需一行代码,效果如下:

using var pool = new ArrayPoolWrapper<int>(5);

具体实现代码如下:

public struct ArrayPoolWrapper<T> : IDisposable
{
    private int _index = -1;
    private bool _disposed = false;
    private readonly int _capacity;
    private readonly T[] _pool;
    public ArrayPoolWrapper(int capacity)
    {
        if (capacity <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(capacity), "The capacity must be greater than 0.");
        }
        this._capacity = capacity;
        _pool = ArrayPool<T>.Shared.Rent(capacity);
    }
    public void Add(T info)
    {
        ThrowIfDisposed();
        _index++;
        if (_index >= _capacity)
        {
            _index--;
            throw new InvalidOperationException("The array pool has reached its capacity.");
        }
        _pool[_index] = info;
    }
    public void Dispose()
    {
        ThrowIfDisposed();
        _disposed = true;
        ArrayPool<T>.Shared.Return(_pool);
    }
    private readonly void ThrowIfDisposed()
    {
        if (_disposed)
        {
            throw new ObjectDisposedException(nameof(ArrayPoolWrapper<T>));
        }
    }
}

我们还可以通过封装来实现更多的扩展API,如:RemoveLastOne以及基于Span的切片操作:

public struct ArrayPoolWrapper<T> : IDisposable
{
    public readonly int Count => _index + 1;
    public readonly Span<T> Values => _pool.AsSpan()[..Count];
    public void RemoveLastOne()
    {
        ThrowIfDisposed();
        if (Count <= 0)
        {
            throw new InvalidOperationException("The array pool is empty.");
        }
        _pool[_index] = default!;
        _index--;
    }
}

使用示例如下:

using var pool = new ArrayPoolWrapper<int>(8);
for (var i = 0; i < 8; i++)
{
    pool.Add(i);
}
pool.RemoveLastOne();
Console.WriteLine(pool.Count);
foreach (var i in pool.Values[1..3])
{
    Console.WriteLine(i);
}

完整的实现代码已在Github上开源。

目录
相关文章
|
3月前
|
人工智能 自然语言处理 安全
【新人快速上手使用】小白也能上手的 OpenClaw 2.6.6 安装教程(技术分享)
OpenClaw(小龙虾)是2026年热门开源「数字员工」,支持Windows一键部署(5分钟搞定),本地运行、零代码、全自动办公。无需配置环境,可整理文件、发邮件、浏览器自动化等,隐私安全,小白友好。
|
3月前
|
存储 数据采集 分布式计算
数据仓库是什么?数据仓库和大数据平台、数据湖、数据中台、湖仓一体有什么区别?
本文厘清数据仓库、大数据平台、数据湖、数据中台、湖仓一体五大核心概念的本质区别与适用场景,破除术语混淆误区。从架构定位、数据类型、建模方式、技术演进到典型优劣,逐一剖析,助你精准选型、科学设计、自信汇报。
|
3月前
|
SQL 关系型数据库 MySQL
EXPLAIN 执行计划:一眼看穿你的SQL慢在哪
数据库小学妹带你轻松掌握SQL性能诊断!通过EXPLAIN查看执行计划,精准识别索引失效、全表扫描(ALL)、key为NULL等瓶颈。聚焦type、key、rows等6个关键字段,结合实战案例与避坑指南(如函数滥用、最左前缀破坏),让优化有的放矢。学完即用,告别盲目调优!
|
3月前
|
JavaScript Windows
node-v0.12.2-x86安装步骤详解(附Node.js历史版本与32位配置教程)
`node-v0.12.2-x86.msi` 是 Node.js 0.12.2 的 32 位 Windows 安装包,发布于 2015 年,适用于需兼容老项目的开发环境。支持 Win7/10/11(32/64 位),安装时建议卸载新版、以管理员身份运行,并务必勾选 npm。验证命令:`node -v`(应显示 v0.12.2)、`npm -v`(如 2.7.4)。
|
3月前
|
JavaScript Android开发 数据安全/隐私保护
以cocos3.8.8开发的游戏为例商业实战项目举例cocos打包ios苹果安装包ipa完整详细教程-优雅草卓伊凡
本教程基于Cocos Creator 3.8.8,详解iOS IPA打包全流程:含环境配置(Xcode、Apple开发者账号)、构建面板设置(包名、屏幕方向、签名等)、Xcode工程配置、Archive归档及IPA导出,并附常见报错解决方案,理论+实操结合,助力开发者高效上架。
431 8
以cocos3.8.8开发的游戏为例商业实战项目举例cocos打包ios苹果安装包ipa完整详细教程-优雅草卓伊凡
|
1月前
|
人工智能 安全 算法
大模型应用:AI 智能体核心引擎:RAG检索增强生成原理与医疗场景深度落地.126
本文详解RAG(检索增强生成)在医疗智能体中的落地实践:针对大模型知识过时、幻觉、专业性不足三大痛点,基于Qwen本地大模型、MiniLM嵌入、FAISS向量库与LangChain框架,实现全流程可追溯、全本地化、无幻觉的精准问答。含环境配置、适配器封装、知识库构建及调试分析。
329 7
|
2月前
|
弹性计算 运维 云计算
阿里云服务器ECS是什么?一张图看懂ECS组成、使用场景、优势及功能详细介绍
阿里云ECS(弹性计算服务)是高性能、高可靠的IaaS云服务器,免采购硬件,即开即用、弹性伸缩。类比“租房”,阿里云代运维机房,用户按需租用、随时释放,降本增效。助力企业快速部署与业务扩展。云服务器ECS官网链接:https://t.aliyun.com/U/AZBUsA
192 3
|
2月前
|
SQL 人工智能 安全
从 BI Copilot 到业务 Agent:指标服务如何成为统一数据接口?
一个能够提供标准化、语义化、服务化数据接口的指标层,正成为数据智能新阶段的战略基础设施。
|
2月前
|
SQL 机器学习/深度学习 自然语言处理
从单模态到多模态:一文看懂智能问数平台如何“读懂”你的表格、文本和图
截至2026年5月,智能问数平台对表格、文本、图等多模态数据的处理已形成四类技术路线:预制SQL、Text2SQL+宽表、预制指标平台及本体语义层。后者在跨模态融合、泛化能力与准确率(闭卷95%+、开卷100%)上优势显著,但需前期语义治理投入;前三者适用固定场景,维护成本随业务扩张呈指数增长。选型关键不在技术优劣,而在匹配组织的数据复杂度、业务变化频率与治理能力。
|
2月前
|
人工智能 自然语言处理 供应链
为什么 MCP 在协议层会有 prompt injection的问题:工具描述如何劫持 agent 上下文
MCP(Model Context Protocol)虽成AI Agent主流集成标准,但其将工具描述全量注入上下文的设计,导致“Context Poisoning”——恶意指令可借工具元数据污染LLM推理。OWASP将其列为LLM应用头号漏洞,2025年已致超10万站点遭袭。根本风险在于协议层信任模型缺失,非清洗不可用。
228 12
为什么 MCP 在协议层会有 prompt injection的问题:工具描述如何劫持 agent 上下文