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.)
Object pools help to reduce resource overhead when you need multiple instances of a class that are expensive to create or manage. If your application involves instantiating the same classes over and over again, use this design pattern to ensure optimal performance.
A connection pool is an object pool that contains connection objects. "Object pooling lets you control the number of connections you use, as opposed to connection pooling, where you control the maximum number reached." An object pool allows an application to limit the number of instances in use at any one time.
Object pooling can offer a significant performance boost in situations where the cost of initializing a class instance is high and the rate of instantiation and destruction of a class is high – in this case objects can frequently be reused, and each reuse saves a significant amount of time.
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 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(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With