【发布时间】:2015-09-07 09:29:22
【问题描述】:
我正在尝试编写一个 subj 队列,但我遇到了死锁和其他多线程问题。我想使用Interlocked.CompareExchange 来避免使用lock。但是这段代码没有按预期工作:它只是擦除整个队列。我在这里做错了什么?
public class FixedSizedQueue<T> : IEnumerable<T>
{
readonly ConcurrentQueue<T> _queue = new ConcurrentQueue<T>();
public int Limit { get; set; }
public FixedSizedQueue(int limit)
{
Limit = limit;
}
public void Enqueue(T obj)
{
_queue.Enqueue(obj);
if (_queue.Count <= Limit)
return;
int count = _queue.Count;
if (_queue.Count != Interlocked.CompareExchange(ref count, count, _queue.Count))
{
T overflow;
while (_queue.TryDequeue(out overflow))
{
}
}
}
public T[] ToArray()
{
return _queue.ToArray();
}
public IEnumerator<T> GetEnumerator()
{
return _queue.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
也许我只需要另一个线程来切断队列......
【问题讨论】:
-
好吧,您的 while 循环清楚地擦除了整个队列。那是行不通的。限制那个循环。
-
引用Eric Lippert:“就拿锁吧。”
-
@Corak tnx 链接,我遵循这个建议
-
使用 BlockingCollection 代替,BoundedCapacity 属性设置限制。它在底层使用 ConcurrentQueue 来实现集合。
标签: c# .net multithreading synchronization queue