Skip to content

Instantly share code, notes, and snippets.

@scionwest
Last active January 7, 2017 05:34
Show Gist options
  • Save scionwest/7eecb1904d25029b20313a79e75baea1 to your computer and use it in GitHub Desktop.
Save scionwest/7eecb1904d25029b20313a79e75baea1 to your computer and use it in GitHub Desktop.
ObjectPool`1.cs

Usage

Instantiation

var objectPool = new ObjectPool<MyObject>(poolSize: 10);

Renting

MyObject obj = objectPool.Rent();

Recycling

objectPool.Return(obj);
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace GameServ
{
public class ObjectPool<TObject>
{
private int maxPoolSize;
private Stack<TObject> poolCache;
private Func<TObject> factory;
public ObjectPool(int poolSize)
{
this.maxPoolSize = poolSize;
this.poolCache = new Stack<TObject>();
}
public ObjectPool(int poolSize, Func<TObject> factory) : this(poolSize)
{
this.factory = factory;
}
public TObject Rent()
{
TObject instance = default(TObject);
Monitor.Enter(this.poolCache);
if (this.poolCache.Count > 0)
{
instance = this.poolCache.Pop();
}
Monitor.Exit(this.poolCache);
if (instance != null)
{
return instance;
}
// New instances don't need to be prepared for re-use, so we just return it.
if (this.factory == null)
{
return (TObject)Activator.CreateInstance(typeof(TObject));
}
else
{
return this.factory();
}
}
public void Return(TObject instanceObject)
{
Monitor.Enter(poolCache);
if (this.poolCache.Count >= this.maxPoolSize)
{
return;
}
// TODO: Convert Stack into an array.
// We'll track the current index by decrementing the index in Rent, and incrementing in Return
// Upon Renting, we'll set pool[index] to null, then reduce index by 1. This lets us manage an
// array and have zero lookup costs.
this.poolCache.Push(instanceObject);
Monitor.Exit(poolCache);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment