Skip to content

Instantly share code, notes, and snippets.

@scionwest
Last active February 25, 2017 21:03
Show Gist options
  • Save scionwest/d64f7822be28d72f7006e63677ea196c to your computer and use it in GitHub Desktop.
Save scionwest/d64f7822be28d72f7006e63677ea196c to your computer and use it in GitHub Desktop.
ObjectPool<T>
public class ObjectPool<TObject> where TObject : class, new()
{
private int maxPoolSize;
private Stack<TObject> poolCache;
private Action<TObject> objectReset;
private Func<TObject> factory;
private bool isObjectResettable;
public ObjectPool(int poolSize)
{
this.maxPoolSize = poolSize;
this.poolCache = new Stack<TObject>();
this.isObjectResettable = typeof(IReusable).GetTypeInfo().IsAssignableFrom(typeof(TObject).GetTypeInfo());
}
public ObjectPool(int poolSize, Action<TObject> objectReset) : this(poolSize)
=> this.objectReset = objectReset;
public ObjectPool(int poolSize, Func<TObject> factory) : this(poolSize)
=> this.factory = factory;
public ObjectPool(int poolSize, Func<TObject> factory, Action<TObject> objectReset) : this(poolSize, objectReset)
=> this.factory = factory;
public TObject Rent()
{
Monitor.Enter(this.poolCache);
if (this.poolCache.Count == 0)
{
Monitor.Exit(this.poolCache);
// New instances don't need to be prepared for re-use, so we just return it.
return this.CreateNewInstance();
}
TObject instance = this.poolCache.Pop();
Monitor.Exit(this.poolCache);
this.TryResettingInstance(instance);
return instance;
}
public void Return(TObject instanceObject)
{
Monitor.Enter(poolCache);
if (this.poolCache.Count >= this.maxPoolSize)
{
Monitor.Exit(poolCache);
return;
}
this.poolCache.Push(instanceObject);
Monitor.Exit(poolCache);
}
private TObject CreateNewInstance() => this.factory == null
? new TObject()
: this.factory();
private void TryResettingInstance(TObject instance)
{
if (this.objectReset != null)
{
this.objectReset(instance);
return;
}
if (this.isObjectResettable)
{
IReusable resettableInstance = (IReusable)instance;
resettableInstance.PrepareForReuse();
return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment