.NET中已存在ObjectPool 或类似内容?

我不想写自己的,因为我担心我可能会遗漏某些东西和/或扯掉其他人的工作,那么.NET库中是否存在ObjectPool(或类似)类?

对象池,我指的是一个帮助缓存需要很长时间才能创建的对象的类,通常用于提高性能。

更新:

我还从TPL DataFlow中提出了BufferBlock 。 IIRC它现在是.net的一部分。 BufferBlock在于,您可以使用PostReceiveAsync扩展方法异步等待项目变为可用。 在异步/等待世界中非常方便。

原始答案

前一阵子我遇到了这个问题,并提出了一个轻量级(粗糙’已经)线程安全(我希望)池,它已被certificate非常有用,可重用和健壮:

  public class Pool where T : class { private readonly Queue> asyncQueue = new Queue>(); private readonly Func createFunction; private readonly HashSet pool; private readonly Action resetFunction; public Pool(Func createFunction, Action resetFunction, int poolCapacity) { this.createFunction = createFunction; this.resetFunction = resetFunction; pool = new HashSet(); CreatePoolItems(poolCapacity); } public Pool(Func createFunction, int poolCapacity) : this(createFunction, null, poolCapacity) { } public int Count { get { return pool.Count; } } private void CreatePoolItems(int numItems) { for (var i = 0; i < numItems; i++) { var item = createFunction(); pool.Add(item); } } public void Push(T item) { if (item == null) { Console.WriteLine("Push-ing null item. ERROR"); throw new ArgumentNullException(); } if (resetFunction != null) { resetFunction(item); } lock (asyncQueue) { if (asyncQueue.Count > 0) { var result = asyncQueue.Dequeue(); result.SetAsCompletedAsync(item); return; } } lock (pool) { pool.Add(item); } } public T Pop() { T item; lock (pool) { if (pool.Count == 0) { return null; } item = pool.First(); pool.Remove(item); } return item; } public IAsyncResult BeginPop(AsyncCallback callback) { var result = new AsyncResult(); result.AsyncCallback = callback; lock (pool) { if (pool.Count == 0) { lock (asyncQueue) { asyncQueue.Enqueue(result); return result; } } var poppedItem = pool.First(); pool.Remove(poppedItem); result.SetAsCompleted(poppedItem); return result; } } public T EndPop(IAsyncResult asyncResult) { var result = (AsyncResult) asyncResult; return result.EndInvoke(); } } 

为了避免池化对象的任何接口要求,对象的创建和重置都由用户提供的委托执行:即

 Pool msPool = new Pool(() => new MemoryStream(2048), pms => { pms.Position = 0; pms.SetLength(0); }, 500); 

在池为空的情况下,BeginPop / EndPop对提供APM(ish)方法,当一个对象可用时异步检索对象(使用Jeff Richter出色的AsyncResult 实现)。

我不太清楚为什么它会被T:class …那么可能没有。

在即将推出的.NET(4.0)版本中,有一个ConcurrentBag类,可以很容易地在ObjectPool实现中使用; 事实上, 有一篇关于MSDN的文章向您展示了如何做到这一点。

如果您无法访问最新的.NET框架,则可以从Microsoft的Reactive Extensions(Rx)库 (在System.Threading中)获取.NET 3.5中的System.Collections.Concurrent命名空间(具有ConcurrentBag )。 DLL)。

CodeProject有一个示例ObjectPool实现。 看看这里 。 或者,这里有一些实现, 这里和这里 。

System.Collections.Generic.Dictionary怎么样?

听起来你需要一个带缓存的Factory模式。

您可以尝试使用.netreflection器来查看ThreadPool实现。