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上开源。

目录
相关文章
|
2天前
|
人工智能 API 开发工具
Claude Code国内安装:2026最新保姆教程(附cc-switch配置)
Claude Code是我目前最推荐的AI编程工具,没有之一。 它可能不是最简单的,但绝对是上限最高的。一旦跑通安装、接上模型、定好规范,你会发现很多原本需要几小时的工作,现在几分钟就能搞定。 这套方案的核心优势就三个字:可控性。你不用依赖任何不稳定服务,所有组件都在自己手里。模型效果不好?换一个。框架更新了?自己决定升不升。 这才是AI时代开发者该有的姿势——不是被动等喂饭,而是主动搭建自己的生产力基础设施。 希望这篇保姆教程,能帮你顺利上车。做出你自己的作品。
Claude Code国内安装:2026最新保姆教程(附cc-switch配置)
|
9天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
3796 21
|
5天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
2375 8
|
4天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
1984 4
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
|
21天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
18881 60
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
|
2天前
|
SQL 人工智能 弹性计算
阿里云发布 Agentic NDR,威胁检测与响应进入智能体时代
欢迎前往阿里云云防火墙控制台体验!
1168 2

热门文章

最新文章