I have implemented a generic ObjectPool class but have experienced that it sometime deadlocks (happens at Monitor.Wait(poolLock))
Can anyone spot the error?
public class ObjectPool<T> where T : new()
{
private readonly object poolLock = new object();
Stack<T> stack = null;
public ObjectPool(int count)
{
stack = new Stack<T>(count);
for (int i=0; i<count; i++)
stack.Push(new T());
}
public T Get()
{
lock (poolLock)
{
//if no more left wait for one to get Pushed
while (stack.Count < 1)
Monitor.Wait(poolLock);
return stack.Pop();
}
}
public void Put(T item)
{
lock (poolLock)
{
stack.Push(item);
//If adding first send signal
if (stack.Count == 1)
Monitor.Pulse(poolLock);
}
}
usage
try
{
service = myPool.Get();
}
finally
{
if (service != null)
myPool.Put(service);
}
The deadlock is probably happening with a
stack.Count > 0. That means you have a Wait/Pulse problem. It is not a bad idea to always call Pulse after a Push(). Or at least when Count < 5 or so. Remember that the Wait/Pulse mechanism does not have a memory.A scenario: