通常の Queue クラスにスレッドセーフなラッパーを実装しようとしています。しかし、複数のスレッドが同じロックを取得する可能性があるようです。私の質問は次のとおり
です。
2. 回避するには?
3. 有益なアドバイスをいただければ幸いです
これは私のキューです:
public class SafeQueue<T> : SimpleQueue<T>
{
private readonly object sync = new object();
private readonly Queue<T> queue = new Queue<T>();
public override T Dequeue()
{
T item;
lock (sync)
{
Debug.Print("{1:mm ss ffff} {0} locked in dequeue", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
item = queue.Dequeue();
}
Debug.Print("{1:mm ss ffff} {0} unlocked dequeue", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
return item;
}
public override void Enqueue(T item)
{
lock (sync)
{
queue.Enqueue( item );
}
}
public override IEnumerator<T> GetEnumerator()
{
Queue<T> q;
lock (sync)
{
q = new Queue<T>(queue);
}
return ((IEnumerable<T>) q).GetEnumerator();
}
public override int Count
{
get
{
int c;
lock (sync)
{
Debug.Print("{1:mm ss ffff} {0} locked in count", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
c = queue.Count;
}
Debug.Print("{1:mm ss ffff} {0} unlocked count. Ret {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now,c);
return c;
}
}
}
そして、これは私がそれを使用する場所からの一部です (作業はスレッド関数です):
private readonly SafeQueue<string> taskQueue = new SafeQueue<string>();
private volatile bool stop = false;
...
private void Work()
{
while ( !stop )
{
string dir = null;
if (taskQueue.Count > 0)
{
dir = taskQueue.Dequeue();
}
...
したがって、問題は基本的に次のとおりです。2 つのスレッドが Count プロパティのロックを取得し、正の値を返します。それ以来、両方とも要素をデキューしようとします。