C# ConcurrentQueue.IsEmpty是否需要内存屏障?

C# ConcurrentQueue.IsEmpty是否需要内存屏障?,c#,.net,concurrency,C#,.net,Concurrency,在查看IsEmpty时,我在MSDN上注意到: 但是,由于此集合旨在并发访问,因此可能会有另一个线程在IsEmpty返回后修改该集合,从而使结果无效 当然这是真的,但这是否也意味着ConcurrentQueue在检查队列是否为空时不使用读取屏障 我想要一段代码,如果并发队列是空的,则检查另一个线程。大概是这样的: while (!queue.IsEmpty) { } Thread.MemoryBarrier(); while (!queue.IsEmpty) { Thread.Memo

在查看IsEmpty时,我在MSDN上注意到:

但是,由于此集合旨在并发访问,因此可能会有另一个线程在IsEmpty返回后修改该集合,从而使结果无效

当然这是真的,但这是否也意味着ConcurrentQueue在检查队列是否为空时不使用读取屏障

我想要一段代码,如果并发队列是空的,则检查另一个线程。大概是这样的:

while (!queue.IsEmpty)
{
}
Thread.MemoryBarrier();
while (!queue.IsEmpty)
{
    Thread.MemoryBarrier();
}
然而。。如果ConcurrentQueue不使用读取屏障,我认为我们需要添加自己的内存屏障,以确保读取正确的数据,如下所示:

while (!queue.IsEmpty)
{
}
Thread.MemoryBarrier();
while (!queue.IsEmpty)
{
    Thread.MemoryBarrier();
}
(顺便说一句:这些只是一个简单的例子来说明这个问题,实际上还有更多的代码)

我的观察正确吗?或者ConcurrentQueue可以处理这个问题,并且第一个实现可以工作吗?(例如,我对“并发”的期望是什么?)


“伯爵”呢?我在MSDN上找不到答案。。。同一个故事?

不,这与记忆障碍无关。这只是简单的情况,其他的东西可能会在你的测试刚刚结束后进入队列,并在队列中添加或删除一些东西

你不应该真正使用
IsEmpty
。改用
TryDequeue
。或者使用
阻止集合

您确实不想在处理
IsEmpty
Count
时开始编写“锁定”队列的代码


(我现在几乎从未使用过
ConcurrentQueue
,因为
BlockingCollection
要好得多,尽管这当然取决于你想做什么。)

那么,如果它使用或不使用内存屏障呢?当您读取返回的数据时,该障碍已成为历史,所有赌注均已取消。@spender好吧,如果它不使用读取障碍,它可能会无限期地循环—这在我看来是一件非常糟糕的事情。是的,如果您在对某个内容进行操作之前对其进行测试,您将面临并发问题。TryDequeue、AddOrUpdate等通过消除对两阶段测试/提交操作的需要来解决这些问题。我现在很少使用BlockingCollection,因为BufferBlock(以及其他TPL数据流)要好得多;)@spender:我们仍然必须支持Windows Server 2003,因此我们不能使用.Net 4.5,所以BufferBlock对我们来说是零使用。:)除非有.NET4的版本吗?当然有。不
wait
关键字,不能使用新的TPL库等:(正确:不需要使用内存障碍。但是,在您选中
IsEmpty
之后,在您对返回值执行操作之前,队列可能会变为空或非空,对此您无能为力。