Garbage collection in .NET can be very expensive, especially for objects on the Large Object Heap (LOH). .NET itself already uses pooling for threads to prevent the costly creation of threads but instead re-uses the already created threads using a thread pool. Catel provides an implementation of pooling using the PoolManager<TPoolable>. This allows both Catel and third party developers to create a pool for large objects so they can be reused.
The documentation uses a byte array of 4096 as poolable object as example
Introduction to the pool manager
The pool manager internally uses a stack to manage the available objects in the pool. It's important to understand how a pool works. The flow diagram below shows how the pool manager deals with objects:
Customizing a pool manager
Catel implements pooling via the PoolManager<TPoolable> class. This class allows the caller to retrieve an object. There is no need to explicitly derive a class from the PoolManager<TPoolable>. It can be customized though.
Customizing the maximum size
By default, the PoolManager<TPoolable> uses a maximum size of 5 MB per poolable type. If, for this example, the maximum size of byte buffers should be 1 MB, use the code below:
var poolManager = new PoolManager<Buffer4096Poolable>(); poolManager.MaxSize = 1024 * 1024 * 1;
If the
Creating a poolable object
Since the objects need to be re-used, it's very important that the PoolManager<TPoolable> knows how to reset objects to the initial state. Therefore every poolable object needs to implement IPoolable which also implements IDisposable. Below is an example implementation of a poolable object.
public class Buffer4096Poolable : IPoolable { private const int BufferSize = 4096; protected IPoolManager _poolManager; public Buffer4096Poolable() { Data = new byte[BufferSize]; } public byte[] Data { get; private set; } public int Size { get { return BufferSize; } } public void Reset() { var buffer = Data; Array.Clear(buffer, 0, buffer.Length); } // Implemented explicitly so it can't be called accidentally void IPoolable.SetPoolManager(IPoolManager poolManager) { _poolManager = poolManager; } public void Dispose() { _poolManager.ReturnObject(this); } }