在功能中添加了哪些 .NET 4.0 System.Collections.Parallel Collection
本文关键字:System Collections Collection Parallel NET 功能 添加 | 更新日期: 2023-09-27 18:01:32
.NET 4.0引入了System.Collections.Concurrent 命名空间:
"System.Collections.Concurrent 命名空间提供了几个 应用来代替 系统中的相应类型。集合和 System.Collections.Generic namespaces 每当多个线程 正在同时访问集合">
-
BlockingCollection<T>
类 -
ConcurrentBag<T>
类 -
ConcurrentQueue<T>
类 -
ConcurrentDictionary<TKey, TValue>
类 -
OrderablePartitioner<TSource>
类 -
Partitioner
类 -
IProducerConsumerCollection<T>
界面
SynchronizedCollection<T>
类(自 .NET 3.0 起可用(:
"提供包含某种类型的对象的线程安全集合 由泛型参数指定为元素">
。位于 System.Collections.Generic
命名空间中。
那么,为什么
SynchronizedCollection<T>
类是线程安全的,但不是并发的呢?
具体是什么使SynchronizedCollection<T>
泛型类与System.Collections.Concurrent
中的集合不同且不兼容?
更新:让我重新表述这个问题:属于 System.Collections.Concurrent
命名空间的所有泛型集合中的共同点和区别新特征是什么,这在SynchronizedCollection<T>
泛型类中不存在(并且在使用时是不可能的(?
我将标题更改为"SynchronizedCollection
.NET 3.0 的功能中添加了哪些 .NET 4.0 System.Collections.Concurrent
集合?但主要是我想知道是什么使它无法在.NET 3.0的基础上做
更新2:关于说明:
"这个问题可能已经在这里有了答案:
同步集合和 其他并发集合?
在我的问题的背景下,答案令人困惑 - 新功能是进化的(使用 pre-.NET 4.0功能(还是革命性的(在 pre-.NET 4.0中不可用(?
以前的线程安全集合类有一个相当大的缺陷,它们不能以线程安全的方式迭代。 迭代通常很难使线程安全,没有干净的方法来使使用迭代器的代码知道在代码迭代集合时添加到集合或删除的项。 唯一真正安全的方法是在进行迭代时锁定对集合的访问。 这是非常不可取的,这样的锁通常会保持很长时间。 下一个最佳方法是制作集合的副本,该副本不会被修改,因此始终可以安全地迭代。 没有人喜欢该解决方案的 O(n( 存储要求。
.NET 1.0 集合类中的 Syncd(( 方法特别麻烦。 Microsoft并没有秘密说明迭代不是线程安全的。 他们甚至添加了代码来检测事故,当线程修改集合时会引发异常。 但是,此异常并不经常发生,并且困惑的 .NET 程序员未能读取警告标签,只是直截了当地假设无论您做什么,线程安全集合肯定是安全的。 好吧,事实并非如此,当集合上的最基本操作不是线程安全的时,将集合称为"线程安全"当然是一个问题。 Microsoft的意思是"它是线程安全的,因为使用线程不会损坏集合"。 程序员读到的是"它是线程安全的"。 Microsoft没有在 .NET 2.0 泛型集合类中重复同样的错误。
此问题已在 .NET 4 中得到解决,迭代新集合不会引发异常。 否则,它们不会执行任何操作来防止代码因读取过时数据而行为异常。 这是一个无法解决的问题,你必须自己解决。
.NET 4.0 的主要重点是并发性。 Microsoft .NET 4.0 中引入了 System.Threading.Tasks 命名空间,因此添加 System.Collections.Concurrent 命名空间也很有意义。 如其他地方所述,System.Collections.Concurrent 中的集合具有高性能,因为它们是以无锁方式实现的。 这不是一件容易的事,我认为这就是为什么Microsoft觉得它属于一个新的主要.NET版本,而不是.NET 3.x的刷新。 AFAIK无锁行为是使用Interlocked.CompareExchange的通用版本实现的,该版本也是.NET 4.0的新功能。
如果您对如何实现System.Collections.Concurrent的类感兴趣,我建议您阅读Joe Duffy的书"Windows上的并发编程",这是他在.NET 4.0发布之前写的。 本书展示了一些并发集合是如何实现的。
链接的副本回答了您问题的"新功能"部分。我在这里只想说这个说明:
是什么使得在.NET 3.0的基础上无法做到
我的猜测是没有什么是不可能的。我怀疑,如果您在 .NET 4.0 中反编译新类并(根据需要更改语法(针对 .NET 3.5 自己创建此类类,它们将很好地工作。
这与在 .NET 3.5 中手动实现Enumerable.Zip
(如果 .NET 4.0 不可用(相同。事实上,我记得在某处看到过针对 .NET 2.0 的类似 LINQ 库的实现(当然没有 C# 语言功能!
通常,对于 .NET,除非库依赖于新的 CLR 功能,否则没有什么可以阻止针对早期版本重新实现库。这种情况的一个值得注意的例子是泛型:在 .NET 2.0 之前,如果不手动操作每个不同的类,也许使用 Codegen 工具(如 CodeSmith(,就无法获得类型安全的集合支持。
因此,如果没有什么能阻止 .NET 3.5 中Concurrent
类的存在,那么Microsoft为什么不创建它们呢?简单的时间和预算 - 运输是一项功能,有些功能不如此重要,因此它们必须等到更高版本。