Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.)

like image 923
Cheeso Avatar asked Nov 04 '09 04:11

Cheeso


People also ask

What are the object pools used in C#?

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.

What is the difference between object pooling and connection pooling in C#?

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.

Why do we need object pooling?

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.


2 Answers

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);     } } 
like image 105
Sam Harwell Avatar answered Oct 19 '22 08:10

Sam Harwell


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(); } 
like image 43
Michael Petito Avatar answered Oct 19 '22 09:10

Michael Petito