C#对象池模式实现 [英] C# Object Pooling Pattern implementation

查看:346
本文介绍了C#对象池模式实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人有实施的共享对象池的策略在SQL连接池的静脉有限的资源一个很好的资源? (也就是将全面实施,它是线程安全的)。

Does anyone have a good resource on implementing a shared object pool strategy for a limited resource in vein of Sql connection pooling? (ie would be implemented fully that it is thread safe).

要在问候@Aaronaught要求澄清池的使用将是负载平衡请求外部服务跟进。把它放在一个场景,可能会更容易立刻明白,而不是我的直接situtation。我有一个会话对象,功能类似于从NHibernate的在的Isession 对象。每个唯一的会话管理它连接到数据库。目前,我有1长时间运行的会话对象和我遇到的问题在我的服务提供商是限速我这个人会议的使用。

To follow up in regards to @Aaronaught request for clarification the pool usage would be for load balancing requests to an external service. To put it in a scenario that would probably be easier to immediately understand as opposed to my direct situtation. I have a session object that functions similarly to the ISession object from NHibernate. That each unique session manages it's connection to the database. Currently I have 1 long running session object and am encountering issues where my service provider is rate limiting my usage of this individual session.

由于缺乏期望,单一会话将被视为他们显然把它当作是自己敲敲打打服务的客户端长时间运行的服务帐户。这使我想到这里我的问题,而不是有1个人的会议上,我将创建不同的会话池和分裂,而不是创建一个单一的焦点,因为我是previously做跨这些多个会话请求到服务。

Due to their lack of expectation that a single session would be treated as a long running service account they apparently treat it as a client that is hammering their service. Which brings me to my question here, instead of having 1 individual session I would create a pool of different sessions and split the requests up to the service across those multiple sessions instead of creating a single focal point as I was previously doing.

希望这样的背景下提供了一些价值,但直接回答大家的一些问题:

Hopefully that background offers some value but to directly answer some of your questions:

问:是昂贵的对象创建结果?
答:否对象是有限的资源池

Q: Are the objects expensive to create?
A: No objects are a pool of limited resources

问:他们将被收购/释放非常频繁结果
答:是,他们再次可以被认为NHibernate的的iSessions其中1通常是获取和释放为每一个页面请求的期限

Q: Will they be acquired/released very frequently?
A: Yes, once again they can be thought of NHibernate ISessions where 1 is usually acquired and released for the duration of every single page request.

问:将一个简单的先来先服务足矣或做你需要的东西更聪明,即,将prevent饥饿结果?
答::一种简单的轮循式配电就足够了,饥饿我假定你的意思是如果有来电堵塞等版本没有可用的会话。这是不是真的适用,因为会话可以通过不同的来电者共享。我的目标是分布在多个会话使用,而不是1单个会话。

Q: Will a simple first-come-first-serve suffice or do you need something more intelligent, i.e. that would prevent starvation?
A: A simple round robin type distribution would suffice, by starvation I assume you mean if there are no available sessions that callers become blocked waiting for releases. This isn't really applicable since the sessions can be shared by different callers. My goal is distribute the usage across multiple sessions as opposed to 1 single session.

我相信这可能是从对象池的正常使用发散这就是为什么我当初离开了这部分的和计划只是为了适应模式允许对象共享,而不是允许曾经发生饥饿的情况。

I believe this is probably a divergence from a normal usage of an object pool which is why I originally left this part out and planned just to adapt the pattern to allow sharing of objects as opposed to allowing a starvation situation to ever occur.

问:什么这样的事情的优先级,懒惰与积极加载等结果?
答:有没有参与其中,为了简单起见,优先只是假设,我将在创建池本身的创建可用对象池

Q: What about things like priorities, lazy vs. eager loading, etc.?
A: There is no prioritization involved, for simplicity's sake just assume that I would create the pool of available objects at the creation of the pool itself.

推荐答案

有对象池的实现的 dotnet的核心加入到基类库(BCL)。您可以读取原始GitHub的问题这里并查看code的<一个href=\"https://github.com/dotnet/corefx/tree/cd37c8db316083368acd61fd83f0b7073bd03486/src/System.Buffers\"相对=nofollow> System.Buffers 的。目前, ArrayPool 是唯一可用的类型,用于游泳池数组:

Object Pooling in .NET Core

The dotnet core has an implementation of object pooling added to the base class library (BCL). You can read the original GitHub issue here and view the code for System.Buffers. Currently the ArrayPool is the only type available and is used to pool arrays:

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核心中看到。因为它是在DOTNET核心BCL,ASP.NET核心可以共享它与其他物体,如Newtonsoft.Json的JSON序列化对象池。您可以阅读<一href=\"http://james.newtonking.com/archive/2015/12/20/json-net-8-0-release-1-allocations-and-bug-fixes\"相对=nofollow>这个的博客帖子上Newtonsoft.Json是怎么做的更多信息。

An example of its usage can be seen in ASP.NET Core. Because it is in the dotnet core BCL, ASP.NET Core can share it's object pool with other objects such as Newtonsoft.Json's JSON serializer. You can read this blog post for more information on how Newtonsoft.Json is doing this.

新的Microsoft罗斯林C#编译器包含<一个href=\"http://source.roslyn.$c$cplex.com/#Microsoft.$c$cAnalysis/ObjectPool%25601.cs,20b9a041fb2d5b00\"相对=nofollow> ObjectPool的的类型,它被用来汇集这通常得到new'ed和垃圾收集往往频繁使用的对象。这减少的量和具有发生垃圾收集操作的大小。有全部采用ObjectPool的几个不同的子实现(参见:<一href=\"http://stackoverflow.com/questions/30618067/why-are-there-so-many-implementations-of-object-pooling-in-roslyn\">Why是否有对象池的这么多实现罗斯林?)。

The new Microsoft Roslyn C# compiler contains the ObjectPool type, which is used to pool frequently used objects which would normally get new'ed up and garbage collected very often. This reduces the amount and size of garbage collection operations which have to happen. There are a few different sub-implementations all using ObjectPool (See: Why are there so many implementations of Object Pooling in Roslyn?).

1 - <一个href=\"http://source.roslyn.$c$cplex.com/#Microsoft.$c$cAnalysis.Workspaces/Utilities/ObjectPools/SharedPools.cs,b2114905209e7df3\"相对=nofollow> SharedPools 的 - 存储20个对象或100的池如果使用BigDefault

1 - SharedPools - Stores a pool of 20 objects or 100 if the BigDefault is used.

// 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 - <一个href=\"http://source.roslyn.$c$cplex.com/#Microsoft.$c$cAnalysis.Workspaces/Formatting/ListPool.cs,1086fa28bcfcb8ca\"相对=nofollow> ListPool 和<一个href=\"http://source.roslyn.$c$cplex.com/#Microsoft.$c$cAnalysis.Workspaces/Formatting/StringBuilderPool.cs,039ef0c630df07c3\"相对=nofollow> StringBuilderPool - 上面专门为列表和StringBuilder的显示没有严格分开的实现,但各地的执行SharedPools包装。因此,这重新使用存储在SharedPools对象池。

2 - ListPool and StringBuilderPool - Not strictly separate implementations but wrappers around the SharedPools implementation shown above specifically for List and StringBuilder's. So this re-uses the pool of objects stored in 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 - <一个href=\"http://source.roslyn.$c$cplex.com/#Microsoft.$c$cAnalysis/PooledDictionary.cs,ebb1ac303c777646\"相对=nofollow> PooledDictionary 和的 PooledHashSet - 这些用ObjectPool的直接和有对象的一个​​完全独立的游泳池。门店128对象池。

3 - PooledDictionary and PooledHashSet - These use ObjectPool directly and have a totally separate pool of objects. Stores a pool of 128 objects.

// 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();
}

这篇关于C#对象池模式实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆