10

私は現在C#アプリケーションを作成しています。私はConcurrentDictionaryを使うのが初めてであるので、スレッドの安全性に関していくつか質問があります。まず、これは私の辞書です:ConcurrentDictionaryの使用に関するいくつかの質問

/// <summary> 
    /// A dictionary of all the tasks scheduled 
    /// </summary> 
    private ConcurrentDictionary<string, ITask> tasks; 

これを私のクラスでインスタンス化し、それを使ってITaskを実装するすべてのオブジェクトを追跡します。マルチスレッド環境でセットアップが正しく動作するようにしたい。

ConcurrentDictionary内の項目数のカウントを複数のスレッドが取得したい場合は、ロックする必要がありますか?

辞書から特定のキーを取得したい場合は、そのキーのオブジェクトを取得し、そのメソッドを呼び出します。ロックする必要はありますか?例:

/// <summary> 
    /// Runs a specific task. 
    /// </summary> 
    /// <param name="name">Task name.</param> 
    public void Run(string name) 
    { 
     lock (this.syncObject) 
     { 
      var task = this.tasks[name] as ITask; 
      if (task != null) 
      { 
       task.Execute(); 
      } 
     } 
    } 

複数のスレッドがRunメソッドを呼び出して、ITaskのExecuteメソッドを呼び出すことができます。私の目的は、すべてのスレッドを安全かつパフォーマンスの高いものにすることです。

答えて

9

人自身が完全にスレッドセーフさConcurrentDictionaryのメソッドとプロパティ:

http://msdn.microsoft.com/en-us/library/dd287191.aspx

は、同時に複数のスレッドによって にアクセスすることができるキーと値のペアのスレッドセーフなコレクションを表します。

これはCountプロパティを含む:

カウントは、スナップショットセマンティクスを有し、カウントが アクセスされた瞬間に ConcurrentDictionaryの項目の数を表します。

しかしこれはは、辞書の内部に保持するオブジェクト自体はスレッドセーフであることを意味するものではありません。つまり、2つのスレッドが同じTaskオブジェクトにアクセスするのを止め、その上でExecuteメソッドを実行しようとすることはありません。Executeを実行しているときに、私はExecute方法は、個々のタスクに連載(ロック)アクセスを好きTask内のロックオブジェクトを持つとロックをお勧めしたい場合:

public class Task 
{ 
    private object _locker = new object(); 

    public void Execute() 
    { 
     lock (_locker) { 
      // code here 
     } 
    } 
} 

これは、少なくとも、すべての個々のタスクはdoesnのことを保証しますExecuteを実行している複数のスレッドがありません。私はこれがあなたの質問の文脈とクラスとメソッドの名前から後になっていることを推測しています。

+0

は '.count'プロパティのスレッドセーフですか?または '.Count()'メソッドを使用していますか?違いはなんですか? – Zapnologica

2

ConcurrentDictionaryのすべてのメソッドは、複数のスレッドから呼び出すことができます。

他のオブジェクト/複数のオブジェクトに同時にアクセスするためにロックを使用する必要がある場合があるため、プログラムの他の部分が同期を必要としないことを保証するものではありません。

I.e.サンプルコードは、タスクを取得して実行するためにロックされます。原子的に複数のオブジェクトにアクセスするためのロックの例を示します。

サイドノート:task.Execute()のロックを確認すると、ほかのスレッドがタスクを並行して実行することができなくなります。これは、達成したいことかもしれませんが、この場合、ConcurrentDictionaryを使用することは過度の可能性があります。

関連する問題