我正试图想出一种方法来安全地线程并且在性能上明智地撤消ConcurrentQueue上的TryDequeue
我目前解决问题的方法是:
lock(_queue) {
_queue = new ConcurrentQueue<IItem>(_queue.Reverse());
_queue.Enqueue(item);
_queue = new ConcurrentQueue<IItem>(_queue.Reverse());
}
但我不知道这是否是最好的方法,因为我手动锁定它。但是我需要确保在此过程中队列不会在另一个线程中被更改。
我必须这样做(我认为)的原因是我做了一个TryPeek,检查退回的项目,如果它符合标准,我做一个TryDequeue,并再次检查,如果它失败了第二次我想做回滚。这有意义吗?
答案 0 :(得分:1)
如果您在阅读时需要锁定对队列的访问权限,则ConcurrentQueue
的目的将被取消。您也可以围绕正常Queue<T>
编写自己的包装器。
public class UndoableQueue<T> // I shouldn't be allowed to name anything, ever.
{
private readonly Queue<T> _queue = new Queue<T>();
private readonly object _lock = new object();
public void Enqueue(T item)
{
lock (_lock)
{
_queue.Enqueue(item);
}
}
public bool TryDequeue(Func<T, bool> verify, out T dequeued)
{
lock (_lock)
{
if (!_queue.Any())
{
dequeued = default(T);
return false;
}
if (verify(_queue.Peek()))
{
dequeued = _queue.Dequeue();
return true;
}
dequeued = default(T);
return false;
}
}
}
TryDequeue
使用一个函数来确定是否返回该项。它与TryDequeue
上的ConcurrentQueue
类似,但如果队列中有项目并且该函数对该项返回true,则返回值。