什么.NET 4.0 System.Collections.Concurrent集合在function中添加到.NET 3.0 SynchronizedCollection?
.NET 4.0引入了System.Collections.Concurrent命名空间:
“ System.Collections.Concurrent命名空间提供了几个线程安全的集合类,每当多个线程同时访问集合时,应该使用它们代替System.Collections和System.Collections.Generic命名空间中的相应类型”
-
BlockingCollection
类 -
ConcurrentBag
类 -
ConcurrentQueue
类 -
ConcurrentDictionary
类 -
OrderablePartitioner
类 -
Partitioner
类 -
IProducerConsumerCollection
接口
SynchronizedCollection
类(自.NET 3.0起可用):
“提供一个线程安全的集合,其中包含generics参数指定的类型的对象作为元素”
…位于System.Collections.Generic
命名空间中。
那么,为什么 SynchronizedCollection
类是线程安全的而不是并发的?
具体是什么使SynchronizedCollection
generics类与System.Collections.Concurrent
集合不同且不兼容?
更新:让我重新解释一个问题:属于System.Collections.Concurrent
命名空间的所有generics集合中的共同点和区分新特性是什么,它在SynchronizedCollection
generics类中不存在(并且在使用时不可能)?
我将标题更改为“.NET 4.0 System.Collections.Concurrent
集合在function中添加到.NET 3.0 SynchronizedCollection
?”。 但大多数情况下,我很想知道是什么让它无法在.NET 3.0的基础上进行
Update2 :关于说明:
“这个问题可能已经有了答案:
SynchronizedCollection和其他并发集合有什么区别? “
答案是在我的问题的背景下混淆 – 新function是进化的(使用预4.0版function)还是革命性的(在.NET 4.0之前不可用)?
.NET 4.0的主要焦点是并发性。 Microsoft在.NET 4.0中引入了System.Threading.Tasks命名空间,因此添加System.Collections.Concurrent命名空间也是有意义的。 如其他地方所述,System.Collections.Concurrent中的集合具有高性能,因为它们以无锁方式实现。 这不是一件容易的事,我认为这就是微软认为它属于新的主要.NET版本而不是刷新.NET 3.x的原因。 AFAIK无锁行为是使用Interlocked.CompareExchange的通用版本实现的,它也是.NET 4.0的新增function。
如果您对如何实现System.Collections.Concurrent类感兴趣,我建议您阅读他在.NET 4.0发布之前编写的 Joe Duffy的书“Windows上的并发编程” 。 该书展示了如何实现一些并发集合。
以前的线程安全集合类有一个相当大的缺陷,它们不能以线程安全的方式进行迭代。 迭代通常很难使线程安全,没有干净的方法来使代码使用迭代器知道在代码迭代集合时添加到集合或从集合中删除的项目。 唯一真正安全的方法是在迭代发生时锁定对集合的访问。 这是非常不受欢迎的,这种锁定通常会持续很长时间。 接下来最好的方法是制作一个集合的副本,一个不会被修改的副本,因此总是可以安全地迭代。 没有人喜欢该解决方案的O(n)存储要求。
.NET 1.0集合类中的Synchronized()方法特别麻烦。 微软没有说明迭代不是线程安全的秘密。 他们甚至添加了代码来检测事故,它在线程修改集合时抛出exception。 然而,这种exception并不经常发生,并且令人困惑的.NET程序员无法读取警告标签并且只是平坦地认为无论你做什么,肯定一个线程安全的集合是安全的。 好吧,当集合上最基本的操作不是线程安全时,它不是并且调用集合“线程安全”当然是一个问题。 微软的意思是“它是线程安全的,因为使用线程不会破坏集合”。 程序员读到的是“它是线程安全的”。 Microsoft在.NET 2.0generics集合类中没有重复同样的错误。
这在.NET 4中得到了解决,迭代新集合不会引发exception。 否则他们不会做任何事情来阻止你的代码行为不端,因为它正在读取过时的数据。 这是一个无法解决的问题,你必须自己解决。
链接的副本回答了问题的“新function”部分。 我将在这里发言:
是什么让它无法在.NET 3.0的基础上做到
我的猜测是不可能的。 我怀疑如果你在.NET 4.0中对新类进行反编译并且(根据需要进行语法更改)自己针对.NET 3.5创建这样的类,它们将非常有效。
这与Enumerable.Zip
的方式相同,如果.NET 4.0不可用, 可以在.NET 3.5中手动实现 。 实际上,我记得在某处可以看到针对.NET 2.0的LINQ类库的实现(当然没有C#语言function!)。
通常使用.NET,除非库依赖于新的CLRfunction,否则没有什么能阻止库针对早期版本重新实现。 这种情况的一个值得注意的例子是generics:在.NET 2.0之前,没有办法获得类型安全集合支持而无需手动处理每个不同的类,可能使用Codegen工具,如CodeSmith 。
因此,如果没有什么能阻止.NET 3.5中Concurrent
类的存在,为什么Microsoft不创建它们呢? 简单的时间和预算 – 运输是一项function,有些function不那么重要,所以他们必须等到更高版本。