1.) The way the object pool is filled happens is async.
2.) Access to a pool instance from the client app is thread safe.
To solve 1, we could exploit the AsyncMethodCaller together with its BeginInvoke(), while to make sure that the access to the pool is thread safe, we could check out the ConcurrentBag in .NET 4.0. So, where is the code?!
namespace HoC.Client { /// <summary> /// maintains a pool/list of objects, provides it on request /// usually used for classes whose construction call is heavy /// </summary> /// <typeparam name="W"></typeparam> public class ObjectInstancePool<W> { private const int objectCount = 20; //can be updated to receive through the constructor private ConcurrentBag<W> objectList = new ConcurrentBag<W>(); public ObjectInstancePool() { //refresh the bag first new AsyncMethodCaller(Filler).BeginInvoke(null, null); } public W GetInstance() { W result; if (!(objectList.TryTake(out result))) { result = Activator.CreateInstance<W>(); } else new AsyncMethodCaller(Filler).BeginInvoke(null, null); //refresh the bag return result; } public delegate void AsyncMethodCaller(); private void Filler() { while (objectList.Count < objectCount) { objectList.Add(Activator.CreateInstance<W>()); } } } }
I totally like it short and sweet :)