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

6

21

I have a class that is expensive to construct, in terms of time and memory. I'd like to maintain a pool of these things and dispense them out on demand to multiple threads in the same process.

Is there a general-purpose object pool that is already tested and proven? (I don't want COM+ pooling.)

Sansone answered 4/11, 2009 at 4:49 Comment(1)
github.com/yanggujun/commonsfornet/wiki/Commons.PoolRhombohedral
F
7

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>

Frayda answered 5/1, 2021 at 21:43 Comment(4)
Annoyingly, there's no IObjectPool<T> in the library, which makes it harder to use projects using DI, or if you want to easily swap-out different pool implementations. *grumble*Overwrite
@Overwrite check out the APIs designed specifically for that, which can be found on nuget in the Microsoft.Extensions.ObjectPool.DependencyInjection package.Wino
@Wino Microsoft.Extensions.ObjectPool.DependencyInjection was first released only 10 months ago; it didn't exist when I wrote my comment two years ago.Overwrite
Yep don't sweat it. It's an update, to direct people to a potentially better alternative, similar to the answer itself, as well as potentially helping you find something that could make your life easier, now, if you weren't aware of the new goodies. :)Wino
O
24

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);
    }
}
Outsmart answered 4/11, 2009 at 5:0 Comment(2)
Thank you, I saw this one. It depends on .NET 4.0. Unfortunately, I am depending on NET 2.0. !!!Sansone
Link, maybe: How to: Create an Object Pool by Using a ConcurrentBagHuoh
F
7

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>

Frayda answered 5/1, 2021 at 21:43 Comment(4)
Annoyingly, there's no IObjectPool<T> in the library, which makes it harder to use projects using DI, or if you want to easily swap-out different pool implementations. *grumble*Overwrite
@Overwrite check out the APIs designed specifically for that, which can be found on nuget in the Microsoft.Extensions.ObjectPool.DependencyInjection package.Wino
@Wino Microsoft.Extensions.ObjectPool.DependencyInjection was first released only 10 months ago; it didn't exist when I wrote my comment two years ago.Overwrite
Yep don't sweat it. It's an update, to direct people to a potentially better alternative, similar to the answer itself, as well as potentially helping you find something that could make your life easier, now, if you weren't aware of the new goodies. :)Wino
L
6

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();
}
Lampe answered 4/11, 2009 at 5:35 Comment(0)
P
5

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.

Psychopath answered 4/11, 2009 at 5:3 Comment(0)
F
1

Why not just write a singleton that just serves as the gateway to the array of objects that has been created.

When an object is handed out, then remove it from the available list, put it in the checked out list, and then when it is returned, reverse that.

By using a singleton for this you have a static class for everything to call, and if the expensive class is an inner class of the singleton, then nothing else can create the expensive class, and you can control how many objects to create, easily.

Fasciculus answered 4/11, 2009 at 4:58 Comment(2)
Well ya, that would work. an object pool can be pretty simple. But then there are additional niceties like, a bounded object population (no lower than x, no higher than y), named objects, object properties, that kinda thing. I just wondered if someone had designed it already and considered these things.Sansone
@Sansone - you may want to add that to your question, as it will change the question quite a bit.Fasciculus
C
0

Just to share. I created a generic .net common pool library using Apache Common pool as a model. http://cobrary.wordpress.com/net-common-pool-library/

Citrange answered 8/4, 2013 at 6:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.