为什么会出现在.net中没有通用同步队列? [英] Why is there no generic synchronized queue in .NET?

查看:240
本文介绍了为什么会出现在.net中没有通用同步队列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,你可以调用Queue.Synchronize获得一个线程安全的队列对象,但同样的方法并不适用于队列和LT; T&取代。有谁知道为什么吗?似乎有种奇怪的。

I noticed that you can call Queue.Synchronize to get a thread-safe queue object, but the same method isn't available on Queue<T>. Does anyone know why? Seems kind of weird.

推荐答案

更新 - 在.NET 4中,还有现在 ConcurrentQueue&LT; T&GT; 在System.Collections.Concurrent,这里记录的<一个href="http://msdn.microsoft.com/en-us/library/dd267265.aspx">http://msdn.microsoft.com/en-us/library/dd267265.aspx.这是有趣的是,它的IsSynchronized方法(正确地)返回false。

Update - in .NET 4, there now is ConcurrentQueue<T> in System.Collections.Concurrent, as documented here http://msdn.microsoft.com/en-us/library/dd267265.aspx. It's interesting to note that its IsSynchronized method (rightly) returns false.

ConcurrentQueue&LT; T&GT; 是一个完整上爬起来重写,创建队列枚举的副本,并采用先进的无锁技术,如互锁.CompareExchange() Thread.SpinWait()

ConcurrentQueue<T> is a complete ground up rewrite, creating copies of the queue to enumerate, and using advanced no-lock techniques like Interlocked.CompareExchange() and Thread.SpinWait().

这个答案的其余部分仍然具有现实意义,因为它涉及到旧同步()和SyncRoot上成员的消亡,为什么他们没有从API的角度很好地工作。

The rest of this answer is still relevant insofar as it relates to the demise of the old Synchronize() and SyncRoot members, and why they didn't work very well from an API perspective.

根据Zooba的评论,首创置业团队认为太多的开发者误解调校的目的(以及在较小程度上,SyncRoot上)

As per Zooba's comment, the BCL team decided that too many developers were misunderstanding the purpose of Synchronise (and to a lesser extent, SyncRoot)

布莱恩Grunkemeyer形容这对BCL团队博客的几年前: <一href="http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx">http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx

Brian Grunkemeyer described this on the BCL team blog a couple of years back: http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx

问题的关键是获得正确的粒度锁左右,一些开发人员会天真地在同步集合使用多个属性或方法,并相信他们的code线程安全的。布赖恩用队列为他的榜样,

The key issue is getting the correct granularity around locks, where some developers would naively use multiple properties or methods on a "synchronized" collection and believe their code to be thread safe. Brian uses Queue as his example,

if (queue.Count > 0) {
    object obj = null;
    try {
        obj = queue.Dequeue();

开发就没有意识到,计数可能被另一个线程出列被调用之前可以更改。

Developers wouldn't realize that Count could be changed by another thread before Dequeue was invoked.

强迫开发者使用周围的整个操作的明确锁定表态意味着preventing这种虚假的安全感。

Forcing developers to use an explicit lock statement around the whole operation means preventing this false sense of security.

由于布赖恩提到,切除SyncRoot上的,部分是因为它主要是推出了支持同步,而且还因为在许多情况下,有一个更好的选择锁对象 - 大多数时候,无论是队列实例本身,或一个

As Brian mentions, the removal of SyncRoot was partly because it had mainly been introduced to support Synchronized, but also because in many cases there is a better choice of lock object - most of the time, either the Queue instance itself, or a

private static object lockObjForQueueOperations = new object();

在类拥有的队列实例...

on the class owning the instance of the Queue...

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

This latter approach is usually safest as it avoids some other common traps:

  • Never lock(this)
  • Don't lock(string) or lock(typeof(A))

正如他们所说,线程很难 ,并使它看起来容易可能是危险的。

As they say, threading is hard, and making it seem easy can be dangerous.

这篇关于为什么会出现在.net中没有通用同步队列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆