次の C# クラスは、マルチスレッド環境で使用されます。実際のコードの大部分を削除しました。この問題は、MethodA と MethodB をほぼ同時に呼び出すと発生します。IsDepleted プロパティのロックの順序は問題を解決しません。IsDepleted プロパティから lock(WaitingQueue) を削除するとデッドロックが解決されますが、この解決策では、別のスレッドが WaitingQueue.Count == 0 ステートメントと Processing.Count == 0 ステートメントの間で WaitingQueue に項目を追加/削除するときに問題が発生します。
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
}
}