The following C# class is used in a multithreaded enviroment. I removed very much of the actual code. The problem occurs when calling MethodA and MethodB almost simultaneously. The order of the lock in the IsDepleted property doesn't solves the problem. Removing lock(WaitingQueue) from the IsDepleted property solves the deadlock, but this solution causes a problem when another thread adds/removes an item from the WaitingQueue between the WaitingQueue.Count == 0 and Processing.Count == 0 statements.
using System.Collections.Generic;
class Example
{
bool IsDepleted
{
get
{
lock (Processing)
{
lock (WaitingQueue)
{
return WaitingQueue.Count == 0
&& Processing.Count == 0;
}
}
}
}
private readonly List<object> Processing = new List<object>();
private readonly Queue<object> WaitingQueue = new Queue<object>();
public void MethodA(object item)
{
lock (WaitingQueue)
{
if (WaitingQueue.Count > 0)
{
if (StartItem(WaitingQueue.Peek()))
{
WaitingQueue.Dequeue();
}
}
}
}
public void MethodB(object identifier)
{
lock (Processing)
{
Processing.Remove(identifier);
if (!IsDepleted)
{
return;
}
}
//Do something...
}
bool StartItem(object item)
{
//Do something and return a value
}
}