2013-07-21 4 views
22

このコードを例として使用しています。次のPersonクラスがあるとします。これはC#でConcurrentdictionaryを反復処理する適切な方法ですか?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace dictionaryDisplay 
{ 
class Person 
{ 
    public string FirstName { get; private set;} 
    public string LastName { get; private set; } 

    public Person(string firstName, string lastName) 
    { 
     this.FirstName = firstName; 
     this.LastName = lastName; 

    } 

    public override string ToString() 
    { 
     return this.FirstName + " " + this.LastName; 
    } 
} 

}

メインプログラム

static void Main(string[] args) 
    { 
     ConcurrentDictionary<int, Person> personColl = new ConcurrentDictionary<int, Person>(); 

     personColl.TryAdd(0, new Person("Dave","Howells")); 
     personColl.TryAdd(1, new Person("Jastinder","Toor")); 

     Person outPerson = null; 
     personColl.TryRemove(0, out outPerson); 


     //Is this safe to do? 
     foreach (var display in personColl) 
     { 
      Console.WriteLine(display.Value); 
     } 





    } 
  1. これは、同時辞書を反復処理の安全な方法は何ですか?そうでない場合、それを行うための安全な方法は何ですか?

  2. 辞書からPersonオブジェクトを削除したいとします。私はtryRemoveメソッドを使用しますが、outPersonオブジェクトで何をしますか?削除されたPersonが辞書に格納されます。 outPersonオブジェクトで完全にクリアするにはどうすればよいですか?

+1

ニットを選択しようとしていませんが、使用するステートメントがありません: 'using System.Collections.Concurrent;'? –

+2

それはそこにあり、ちょうどそれを含んでいませんでした。 –

答えて

32

これは、同時辞書を反復処理の安全な方法は何ですか?そうでない場合、それを行うための安全な方法は何ですか?

はい、例外は発生しません。反復を開始した後に要素が追加または削除された場合、要素は繰り返しに含まれる場合と含まれない場合があります。 GetEnumerator documentation:

から列挙子は辞書から返されたと同時に使用しても安全です読み取りと辞書に書き込み、しかし、それは辞書の瞬間インタイムスナップショットを表すものではありません。列挙子を介して公開される内容には、GetEnumeratorが呼び出された後で辞書に加えられた変更が含まれることがあります。

次へ:

私はtryRemoveメソッドを使用しますが、私はoutPersonオブジェクトに何をしますか?

何も必要ではありません。あなただけのIDictionary<TKey, TValue>に辞書をキャストしRemoveを呼び出すか、単にTryRemoveを使用し、その後、変数を無視することができます:

Person ignored; 
dictionary.TryRemove(key, out ignored); 

は「完全にクリア[オブジェクト]」の概念はありません - あなたはすべての参照を持っていない場合それには、ガベージコレクションされます。しかしどちらの方法でも、それは辞書にはもうありません(少なくともそのキーを介して)。コード内の他の場所で変数(上記のignored)を使用しないと、オブジェクトがガベージコレクションされなくなりません。

+1

あなたの説明をありがとう!とても有難い。 –

+3

私はこの質問を見て、すぐにジョン・スケートからの答えがあることを知っていました。 – davnicwil

+0

@ Jon Skeet - これをキャストする正しい方法でしょうか? IDictionary removefromColl =(IDictionary )personColl; –

2

thisの記事をご覧ください。

TryRemove() was added to attempt atomic, safe removes. 

    To safely attempt to remove a value we need to see if the key exists first, this checks for existence and removes under an atomic lock. 

TryRemoveはコレクションからアイテムを削除するので、キーの値が必要な場合があります。

foreachで反復することは安全です。例外はありません。

+0

OP *にはキーがあります。彼らはあなたに何がないと思うのですか? 「このコードを使用しているのは一例です」ということに留意してください。実際のコードが複数のスレッドを使用しないと考える理由はありません。 –

+0

私はその鍵が何に対応していたのかという価値を意味しました。それはアメリカの英語のものでなければなりません。 – DarthVader

+0

しかし、OPのポイントは、キーに対応する値を知る必要はないからです。そのため、彼らは 'out'パラメータを使って何をすべきか分かりませんでした。それはとにかく私がそれに答えた方法です... –

関連する問題