web-dev-qa-db-ja.com

同時辞書の正しい使用法

これが並行辞書の正しい使い方だと思うのは正しいですか

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;

ロックなどはなく、複数のスレッドが同じことをしようとしても、辞書の値を更新するだけです。

74
Jon

スレッドセーフの意味に依存します。

MSDNから- 方法:ConcurrentDictionaryにアイテムを追加および削除する

ConcurrentDictionary<TKey, TValue>は、マルチスレッドシナリオ向けに設計されています。コレクションでアイテムを追加または削除するために、コードでロックを使用する必要はありません。ただし、あるスレッドが値を取得し、別のスレッドが同じキーに新しい値を与えることでコレクションをすぐに更新することは常に可能です。

そのため、ディクショナリ内のアイテムの値の一貫性のないviewを取得することが可能です。

67
Oded

これを見つける最良の方法は、MSDNドキュメントを確認することです。

ConcurrentDictionaryのページは http://msdn.Microsoft.com/en-us/library/dd287191.aspx

スレッドセーフセクションでは、「ConcurrentDictionary(Of TKey、TValue)のすべてのパブリックメンバーおよび保護メンバーはスレッドセーフであり、複数のスレッドから同時に使用できます。」と記述されています。

したがって、並行性の観点からは問題ありません。

4
Erdem

はい、あなたは正しいです。

それと、あるスレッドで辞書を列挙し、別のスレッドで辞書を変更する可能性が、そのクラスの唯一の存在手段です。

2
Jan

私の場合、この方法を使用することを好みます。

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

メソッドの使用方法の詳細については、 MSDNライブラリ を参照してください。

サンプル使用法:

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

注:線形ループでConcurrentDicitonaryオブジェクトを使用しても正当化されず、十分に活用されません。次の例に従って、 Oded Parallelismを使用して言及されているように、Microsoftドキュメントの推奨事項に従うことをお勧めします。

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