C#在ConcurrentQueue上撤消TryDequeue

时间:2017-05-30 14:59:24

标签: c# multithreading queue

我正试图想出一种方法来安全地线程并且在性能上明智地撤消ConcurrentQueue上的TryDequeue

我目前解决问题的方法是:

lock(_queue) {
    _queue = new ConcurrentQueue<IItem>(_queue.Reverse());
    _queue.Enqueue(item);
    _queue = new ConcurrentQueue<IItem>(_queue.Reverse());
}

但我不知道这是否是最好的方法,因为我手动锁定它。但是我需要确保在此过程中队列不会在另一个线程中被更改。

我必须这样做(我认为)的原因是我做了一个TryPeek,检查退回的项目,如果它符合标准,我做一个TryDequeue,并再次检查,如果它失败了第二次我想做回滚。这有意义吗?

1 个答案:

答案 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,则返回值。