ConcurrentDictionary<TKey, TValue>
Class 表示一个线程安全的键值对集合,可以被多个线程同时访问。
但据我所知,System.Collections.Concurrent
类是为 PLINQ 设计的。
我有Dictionary<Key,Value>
它将在线客户端保持在服务器中,当我可以访问它时,我通过锁定对象使其线程安全。
我可以安全地替换 Dictionary<TKey,TValue>
吗?通过 ConcurrentDictionary<TKey,TValue>
在我的情况下?更换后性能会提高吗?
Here在第 5 部分中,Joseph Albahari 提到它是为并行编程而设计的
- 并发集合针对并行编程进行了调整。传统集合在除高并发场景外的所有场景中都优于它们。
- 线程安全的集合并不能保证使用它的代码也是线程安全的。
- 如果您枚举并发集合,而另一个线程正在修改它,则不会抛出异常。相反,您会混合使用新旧内容。
- List 没有并发版本。
- 并发堆栈、队列和包类在内部使用链表实现。这使得它们的内存效率低于非并发 Stack 和 Queue 类,但更适合并发访问,因为链表有利于无锁或低锁实现。 (这是因为将节点插入链表只需要更新几个引用,而将元素插入类似列表的结构可能需要移动数千个现有元素。)
最佳答案
如果不进一步了解您在锁中所做的事情,就不可能说。
例如,如果您所有的字典访问方式如下所示:
lock(lockObject)
{
foo = dict[key];
}
... // elsewhere
lock(lockObject)
{
dict[key] = foo;
}
然后您可以将其关闭(尽管您可能看不到任何性能差异,因此如果它没有损坏,请不要修复它)。但是,如果您在与字典交互的锁定 block 内做任何花哨的事情,那么您必须确保字典提供一个单一函数来完成您正在做的事情在 lock block 中,否则你最终会得到功能上与以前不同的代码。最重要的是要记住,字典只保证对字典的并发调用以串行方式执行;它无法处理您在您的 代码中执行多次与字典交互的单个操作的情况。像这样的情况,当 ConcurrentDictionary
不考虑时,需要您自己的并发控制。
值得庆幸的是,ConcurrentDictionary
为更常见的多步操作提供了一些辅助函数,例如 AddOrUpdate
或 GetOrAdd
,但它们无法涵盖每一种情况。如果您发现自己必须努力将您的逻辑硬塞到这些函数中,那么处理您自己的并发性可能会更好。
关于c# - ConcurrentDictionary<TKey,TValue> 与 Dictionary<TKey,TValue>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5303472/