Is there a general-purpose object pool for .NET?

Pulled straight from MSDN, here's an example of using one of the new concurrent collection types in .NET 4:

The following example demonstrates how to implement an object pool with a System.Collections.Concurrent.ConcurrentBag<T> as its backing store.

public class ObjectPool<T>
{
    private ConcurrentBag<T> _objects;
    private Func<T> _objectGenerator;

    public ObjectPool(Func<T> objectGenerator)
    {
        if (objectGenerator == null)
            throw new ArgumentNullException("objectGenerator");
        _objects = new ConcurrentBag<T>();
        _objectGenerator = objectGenerator;
    }

    public T GetObject()
    {
        T item;
        if (_objects.TryTake(out item))
            return item;
        return _objectGenerator();
    }

    public void PutObject(T item)
    {
        _objects.Add(item);
    }
}

The accepted answer is no longer correct in 2021.

There is Microsoft.Extensions.ObjectPool NuGet package, that provides two implementations of object pool DefaultObjectPool<T> and LeakTrackingObjectPool<T>


The ObjectPool class proposed by 280Z28 looks pretty good. You might also consider creating another class that implements IDisposable and wraps the return value of GetObject(). This will ensure objects are returned to your pool and reads nicely:

class ObjectPoolReference<T> : IDisposable
{
    public ObjectPool<T> Pool { get; private set; }

    public T Instance { get; private set; }

    public ObjectPoolReference(ObjectPool<T> pool, T instance)
    {
        Pool = pool;
        Instance = instance;
    }

    ~ObjectPoolReference()
    {
        Dispose();
    }

    #region IDisposable Members

    private bool _Disposed = false;

    public void Dispose()
    {
        if (!_Disposed)
        {
            Pool.PutObject(Instance);

            _Disposed = true;
        }
    }

    #endregion
}

//instance of the pool
ObjectPool<Foo> Pool;

//"using" ensures the reference is disposed at the end of the block, releasing the object back to the pool
using (var Ref = Pool.GetObject())
{
    Ref.Instance.DoSomething();
}

No Cheeso, there is no general object pool like this. But it is a good idea. I think this would be pretty simple to develop. The key thing is making it work well in a threaded environment.

I think this is an interesting design problem. For example, if this needs to to scale on sever class hardware -and- you will give objects to indivudual threads often then you might do this:

  1. Keep a single central pool of objects.
  2. Keep a per-thread pool (a cache) that is populated when its called for the first time for a thread, and when it becomes empty.

This way, you avoid per-thread contention for most requests.

Different operational conditions would lead you to a different design. For example, if object allocations are rare or the number of threads is low, then it might be simpler just to have a lock around a collection. This won't scale well, but in this case, it would need to.

If you design the class or interface correctly, then you could change the implementation over time to handle more complex scenarios.