为什么.NET中没有通用的同步队列?

为什么.NET中没有通用的同步队列?,.net,generics,synchronization,queue,.net,Generics,Synchronization,Queue,我注意到,您可以调用Queue.Synchronize来获取线程安全的队列对象,但在队列上不能使用相同的方法。有人知道为什么吗?看起来有点奇怪。(我想你是说第二个排队。) 我无法具体回答这个问题,除了IsSynchronized和SyncRoot属性(但不是Synchronize())是从ICollection接口继承的。没有一个泛型集合使用此选项,ICollection接口不包括SyncRoot 至于为什么没有包括在内,我只能推测,它们没有按照图书馆设计师的意图被使用,或者它们没有被充分利用来

我注意到,您可以调用Queue.Synchronize来获取线程安全的队列对象,但在队列上不能使用相同的方法。有人知道为什么吗?看起来有点奇怪。

(我想你是说第二个排队。)

我无法具体回答这个问题,除了IsSynchronized和SyncRoot属性(但不是Synchronize())是从ICollection接口继承的。没有一个泛型集合使用此选项,ICollection接口不包括SyncRoot


至于为什么没有包括在内,我只能推测,它们没有按照图书馆设计师的意图被使用,或者它们没有被充分利用来证明将它们保留在较新的馆藏中是合理的。

你可能会发现平行CTP值得一看;这里有一篇来自那些正在整理这篇文章的人的博文,这是一篇非常热门的博文:


这不完全是一回事,但它可能会解决你更大的问题。(他们甚至以
队列
并发队列
为例。)

更新-在.NET 4中,System.Collections.Concurrent中现在有了
并发队列
,如本文所述。有趣的是,它的IsSynchronized方法(正确地)返回false

ConcurrentQueue
是一种完全从头重写,创建要枚举的队列副本,并使用高级无锁技术,如
Interlocked.CompareExchange()
Thread.SpinWait()

这个答案的其余部分仍然与旧的Synchronize()和SyncRoot成员的消亡有关,从API的角度来看,它们为什么不能很好地工作


根据Zooba的评论,BCL团队认为太多开发人员误解了Synchronise的目的(SyncRoot的误解程度较小)

Brian Grunkemeyer在几年前的BCL团队博客上描述了这一点:

关键问题是获得锁的正确粒度,一些开发人员会天真地在“同步”集合上使用多个属性或方法,并相信他们的代码是线程安全的。Brian以队列为例

if (queue.Count > 0) {
    object obj = null;
    try {
        obj = queue.Dequeue();
开发人员不会意识到,在调用出列之前,计数可以由另一个线程更改

强制开发人员在整个操作中使用显式锁语句意味着防止这种错误的安全感

正如Brian提到的,SyncRoot的删除部分是因为它主要是为了支持Synchronized而引入的,但也因为在许多情况下,锁对象的选择更好—大多数情况下,要么是队列实例本身,要么是

private static object lockObjForQueueOperations = new object();
在拥有队列实例的类上

后一种方法通常是最安全的,因为它避免了一些其他常见陷阱:


正如他们所说,让它看起来简单可能是危险的。

现在,在.Net 4.0中有一个:

ConcurrentQueue<T> 
ConcurrentQueue
在System.Collections.Concurrent中


我不同意你的建议。有趣的是,MSDN的锁文档中说“通常,表达式会是这个”是的,他们在.NET 1.1文档中弄错了,请查看最新的.NET 4版本以获得更正。。。