using System.Collections.Generic; namespace TestPooling.Pool { using System; using System.Collections.Concurrent; using System.Linq; public class ManagedPool : IDisposable where T : class { private static readonly ConcurrentStack> Pool = new ConcurrentStack>(); private readonly Func Factory; public readonly int PartitionSize; private readonly IList> partitions = new List>(); private LinkedList currentPartition; private LinkedListNode currentNode; private int entryIndex = 0; public static int InstanceCount { get { return Pool.Sum(p => p.Count); } } public ManagedPool(int partitionSize, Func factory) { PartitionSize = partitionSize; Factory = factory; } public T Get() { if (currentPartition == null || entryIndex == PartitionSize) { currentPartition = GetPartition(); currentNode = currentPartition.First; entryIndex = 0; partitions.Add(currentPartition); } T entry; if (currentNode == null) { entry = Factory(); currentPartition.AddLast(entry); } else { entry = currentNode.Value; currentNode = currentNode.Next; } entryIndex++; return entry; } private LinkedList GetPartition() { LinkedList partition; return Pool.TryPop(out partition) ? partition : new LinkedList(); } public void Dispose() { Pool.PushRange(partitions.ToArray()); } } }