ConcurrentQueue <t> .TryPeek()?</t>的用例是什么?

时间:2014-04-02 12:08:18

标签: c# multithreading .net-4.0 task-parallel-library

受我当前问题的启发,这与此类似: Analogue of Queue.Peek() for BlockingCollection when listening to consuming IEnumerable<T>区别于我 - 目前正在使用ConcurrentQueue<T>而不是BlockingCollection<T>,我想知道ConcurrentQueue<T>.TryPeek()的任何用例可能是什么?

当然,我的意思是没有手动lock(myQueue)内容的用例来序列化队列访问,因为TPL旨在改进/替换这些锁定。

6 个答案:

答案 0 :(得分:8)

我有一个使用ConcurrentQueue<T>.TryPeek效果很好的应用程序。设置了一个线程来监视队列。它主要是关注队列大小,但我们也希望了解延迟。因为队列中的项目有一个时间戳字段,表示它们被放入队列的时间,我的监控线程可以调用TryPeek来获取队列头部的项目,从当前减去插入时间时间,并告诉我该项目在队列中的时间。随着时间的推移和许多样本,这让我非常清楚地了解了收到的物品需要多长时间。

当我的监控代码仍在检查时,其他一些线程可能会将项目出列并不重要。

我可以想到一些其他情况,在这些情况下,查看队列头部的内容会很有用,即使它可能会立即被取消。

答案 1 :(得分:1)

我有一个ConcurrentQueue,其中许多主题可能Enqueue,但我只限制TryPeekTryDequeue之间的lock和<{1}}的一个主题:

lock (dequeueLock)
    if (queue.TryPeek(out item))
        if (item.Value <= threshold)
            queue.TryDequeue(out item);

注意:此代码运行时,其他线程可能会继续Enqueue

进行一些原子查看 - 检查 - 出列操作会更好,但lock对我的情况来说很好。

答案 2 :(得分:0)

我的理解是,当您想要查看时使用此方法,但您不确定队列中是否有项目。通常,Peek在空队列中会抛出异常。如果项目不存在,TryPeek将返回false。这在多线程场景中非常有用,在这种情况下,另一个线程可能会在检查空队列和实际查看值之间将项目出列。

答案 3 :(得分:0)

TryPeek用于等待对象位于队列的第一个位置。 TryDequeue将使任何对象出列。因此,例如,我编写了一个多线程的Web服务器,但在授权期间,当为某个请求启用授权时,他们需要在一个点按照接收顺序进行处理。我不想锁定整个线程函数或它的一半,只是为了对某些客户端我可以按顺序处理它们的请求。

所以,我创建了一个Dictionary<string, ConcurrentQueue<HttpListenerContext>>,然后在服务器线程的最开始,我暂时锁定并检查是否需要授权,如果是,我将HttpListenerContext存储在队列中使用客户端IP作为字典键,以便不同的客户端不会不必要地阻塞彼此的线程。然后,我处理标头并正常计算哈希值,因为页面可能在初始化之后使用ajax和websockets连接发出两个或三个请求,最好多线程化授权信息的散列(这是我为HttpListener实现的摘要授权)我自己,所以我不限于使用Active Directory)。然后,当需要检查授权时,所谓的客户端现时计数仅比该客户端会话的最后一个请求(安全性功能)大一个,我使用我创建的que和TryPeek { {1}}要等到线程Thread.Yield()是队列中第一个完成授权然后将其出列的队列。

简而言之,它可以用于多线程,对于大多数你希望并行运行的线程来说,利用不同的核心,但是对于它们中的一些线程,你需要一切都按顺序返回

答案 4 :(得分:0)

试试吧

T item = bc.GetConsumingEnumerable().FirstOrDefault();
if (item != null)
{
 //...
}

答案 5 :(得分:0)

在取出对象之前先查看对象是否有效,只是记住,当您执行此操作时,并发队列将创建一个引用,并且在使对象出队时不会从内存中释放该对象。如果这样做,并且您像我对ConcurrentQueue所做的那样对内存进行性能分析,您将看到类似这样的内容。

enter image description here

请注意ConcurrentQueueSegment具有11060个实例,而队列仅包含8个。