ArrayPoolWrapper简洁、安全的ArrayPool

发布时间:2026/6/25 14:00:33

ArrayPoolWrapper简洁、安全的ArrayPool 通过.NET中的 ArrayPool 我们可以实现对T[]类型的池化避免频繁的分配内存和GC以提升性能。鉴于已有不少博客介绍ArrayPool的具体原理本文不会涉及其实现细节。本文聚焦使用中的痛点并提供简洁的封装方案以提升ArrarPool使用的便捷性。ArrayPool本身的使用方式比较简单using System.Buffers; ​ var pool ArrayPoolint.Shared.Rent(4); // 其他逻辑 ArrayPoolint.Shared.Return(pool);为了确保在发生异常时能够释放资源通常需要写成如下形式的样板代码int[] pool null!; try { pool ArrayPoolint.Shared.Rent(4); // 其他逻辑 } finally { if (pool ! null) { ArrayPoolint.Shared.Return(pool); } }以上写法会是我们的代码中充斥大量的样板代码和大量的嵌套影响代码后续的可读性和可维护性。接下来我们在原ArrayPool的基础上稍加封装以实现简洁、安全的使用ArrayPool的目标封装后的使用只需一行代码效果如下using var pool new ArrayPoolWrapperint(5);具体实现代码如下public struct ArrayPoolWrapperT : 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 ArrayPoolT.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; ​ ArrayPoolT.Shared.Return(_pool); } ​ ​ private readonly void ThrowIfDisposed() { if (_disposed) { throw new ObjectDisposedException(nameof(ArrayPoolWrapperT)); } } }我们还可以通过封装来实现更多的扩展API如RemoveLastOne以及基于Span的切片操作public struct ArrayPoolWrapperT : IDisposable { public readonly int Count _index 1; public readonly SpanT 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 ArrayPoolWrapperint(8); for (var i 0; i 8; i) { pool.Add(i); } ​ pool.RemoveLastOne(); Console.WriteLine(pool.Count); ​

相关新闻