并发字典正确用法

时间:2011-11-22 11:07:16

标签: c# .net multithreading .net-4.0 concurrency

我是否正确地认为这是正确使用并发字典

private ConcurrentDictionary<int,long> myDic = new ConcurrentDictionary<int,long>();

//Main thread at program startup

for(int i = 0; i < 4; i++)
{
  myDic.Add(i, 0);
}

//Seperate threads use this to update a value

myDic[InputID] = newLongValue;

我没有锁等,只是更新了字典中的值,即使多个线程可能试图这样做。

5 个答案:

答案 0 :(得分:64)

这取决于线程安全的含义。

来自MSDN - How to: Add and Remove Items from a ConcurrentDictionary

  

ConcurrentDictionary<TKey, TValue>专为多线程场景而设计。您不必在代码中使用锁来添加或删除集合中的项。但是,一个线程总是可以检索一个值,而另一个线程可以通过为相同的键提供一个新值来立即更新集合。

因此,可能会在字典中获得项目值的不一致视图

答案 1 :(得分:4)

最好的方法是查看MSDN文档。

对于ConcurrentDictionary,页面为http://msdn.microsoft.com/en-us/library/dd287191.aspx

在线程安全部分,声明“ConcurrentDictionary(Of TKey,TValue)的所有公共成员和受保护成员都是线程安全的,可以从多个线程同时使用。”

所以从并发的角度来看你没问题。

答案 2 :(得分:2)

是的,你是对的。

在一个线程上枚举字典并在另一个线程上更改字典的可能性是该类存在的唯一方法。

答案 3 :(得分:1)

这取决于我的情况,我更喜欢使用这种方法。

ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>);

有关方法使用的详细信息,请参阅MSDN Library

样本用法:

results.AddOrUpdate(
  Id,
  id => new DbResult() {
     Id = id,
     Value = row.Value,
     Rank = 1
  },
  (id, v) =>
  {
     v.Rank++;
     return v;
  });

答案 4 :(得分:0)

仅需注意:不能使用带有线性循环的 ConcurrentDicitonary 对象来证明其不足。最好的替代方法是按照下面的示例,按照Oded使用Parallelism的方法遵循Microsoft文档的建议:

Parallel.For(0, 4, i => 
{
   myDic.TryAdd(i, 0);
});