c# - ConcurrentDictionary<TKey,TValue> 与 Dictionary<TKey,TValue>

标签 c# c#-4.0 dictionary concurrent-collections

作为MSDN says

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 为更常见的多步操作提供了一些辅助函数,例如 AddOrUpdateGetOrAdd,但它们无法涵盖每一种情况。如果您发现自己必须努力将您的逻辑硬塞到这些函数中,那么处理您自己的并发性可能会更好。

关于c# - ConcurrentDictionary<TKey,TValue> 与 Dictionary<TKey,TValue>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5303472/

相关文章:

c# - 统一 5 错误 : Failed to re-package resources

c# - 如何不丢失绑定(bind)源更新?

c# - 在 TPH 上使用 EF 包含

c# - 如何硬编码查找编辑

c# - 如何设置float2类型的HLSL参数?

c# - 如何让你的对象在比较时充当另一种类型?

c# - 集合查找;字典的替代品

c# - 使用数据注释进行验证

python - 将 json 转储到文件时,键 (0, 0) 不是字符串 - python

c++ - 如何在 C++ 中迭代一个充满字符串的 std::map