您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

C#对象池模式实现

C#对象池模式实现

DOTNET芯具有添加到该基类库(BCL)对象池的实施方案。您可以在此处阅读原始的GitHub问题并查看System.Buffers代码。当前,ArrayPool是唯一可用的类型,用于合并数组。有一个很好的博客文章在这里

namespace System.Buffers
{
    public abstract class ArrayPool<T>
    {
        public static ArrayPool<T> Shared { get; internal set; }

        public static ArrayPool<T> Create(int maxBufferSize = <number>, int numberOfBuffers = <number>);

        public T[] Rent(int size);

        public T[] Enlarge(T[] buffer, int newSize, bool clearBuffer = false);

        public void Return(T[] buffer, bool clearBuffer = false);
    }
}

在ASP.NET Core中可以看到其用法示例。因为它在dotnet核心BCL中,所以ASP.NET Core可以与其他对象(例如Newtonsoft.Json的JSON序列化器)共享它的对象池。您可以阅读博客文章,以获得有关Newtonsoft.Json如何执行此操作的更多信息。

新的Microsoft Roslyn C#编译器包含ObjectPool类型,该类型用于合并经常使用的对象,这些对象通常会被更新并非常频繁地收集垃圾。这减少了必须执行的垃圾收集操作的数量和大小。有几个不同的子实现都使用ObjectPool(请参阅:为什么在Roslyn中有这么多的对象池实现?)。

1-SharedPools-存储20个对象的池,如果使用BigDefault,则存储100个对象。

// Example 1 - In a using statement, so the object gets freed at the end.
using (PooledObject<Foo> pooledObject = SharedPools.Default<List<Foo>>().GetPooledObject())
{
    // Do something with pooledObject.Object
}

// Example 2 - No using statement so you need to be sure no exceptions are not thrown.
List<Foo> list = SharedPools.Default<List<Foo>>().AllocateAndClear();
// Do something with list
SharedPools.Default<List<Foo>>().Free(list);

// Example 3 - I have also seen this variation of the above pattern, which ends up the same as Example 1, except Example 1 seems to create a new instance of the IDisposable [PooledObject<T>][4] object. This is probably the preferred option if you want fewer GC's.
List<Foo> list = SharedPools.Default<List<Foo>>().AllocateAndClear();
try
{
    // Do something with list
}
finally
{
    SharedPools.Default<List<Foo>>().Free(list);
}

2-ListPoolStringBuilderPool-不是严格分开实现,而是围绕上面显示的SharedPools实现进行包装,专门用于List和StringBuilder。因此,这将重用存储在SharedPools中的对象池。

// Example 1 - No using statement so you need to be sure no exceptions are thrown.
StringBuilder stringBuilder= StringBuilderPool.Allocate();
// Do something with stringBuilder
StringBuilderPool.Free(stringBuilder);

// Example 2 - Safer version of Example 1.
StringBuilder stringBuilder= StringBuilderPool.Allocate();
try
{
    // Do something with stringBuilder
}
finally
{
    StringBuilderPool.Free(stringBuilder);
}

3-PooledDictionaryPooledHashSet-它们直接使用ObjectPool并具有完全独立的对象池。存储128个对象的池。

// Example 1
PooledHashSet<Foo> hashSet = PooledHashSet<Foo>.GetInstance()
// Do something with hashSet.
hashSet.Free();

// Example 2 - Safer version of Example 1.
PooledHashSet<Foo> hashSet = PooledHashSet<Foo>.GetInstance()
try
{
    // Do something with hashSet.
}
finally
{
    hashSet.Free();
}

该库提供MemoryStream对象池。它是的直接替代品System.IO.MemoryStream。它具有完全相同的语义。它是由Bing工程师设计的。在此处阅读博客文章或在GitHub上查看代码

var sourceBuffer = new byte[]{0,1,2,3,4,5,6,7}; 
var manager = new RecyclableMemoryStreamManager(); 
using (var stream = manager.GetStream()) 
{ 
    stream.Write(sourceBuffer, 0, sourceBuffer.Length); 
}

注意,RecyclableMemoryStreamManager应该声明一次,它将在整个过程中都有效-这就是池。如果需要,可以使用多个池。

c# 2022/1/1 18:14:05 有557人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶