11

現在、C# アプリケーションを作成しています。私は 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();
            }
        }
    }

ITask の Execute メソッドを呼び出すために、複数のスレッドが Run メソッドを呼び出す可能性があることに注意してください。私の目標は、すべてをスレッド セーフにし、可能な限りパフォーマンスを高めることです。

4

2 に答える 2

10

それら自体のメソッドとプロパティConcurrentDictionaryは完全にスレッドセーフです。

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

複数のスレッドから同時にアクセスできるキーと値のペアのスレッドセーフなコレクションを表します。

これには、Countプロパティが含まれます。

Countにはスナップショットのセマンティクスがあり、Countにアクセスした時点でのConcurrentDictionary内のアイテムの数を表します。

ただし、これは、ディクショナリ内に保持されているオブジェクト自体がスレッドセーフであることを意味するものではありません。つまり、2つのスレッドが同じオブジェクトにアクセスし、そのオブジェクトでメソッドTaskを実行しようとするのを阻止するものは何もありません。Executeメソッドの個々のタスクへのシリアル化された(ロックされた)アクセスが必要な場合は、Execute内部Taskにロックオブジェクトを配置し、実行時にロックすることをお勧めしますExecute

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

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

これにより、少なくともすべての個々のタスクで複数のスレッドが実行されないことが保証されますExecute。質問のコンテキストとクラスとメソッドの名前から、これがあなたが求めているものだと思います。

于 2012-05-09T03:04:03.773 に答える
2

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

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

つまり、サンプル コードは、タスクの取得と実行の両方に対してロックを行います。複数のオブジェクトにアトミックにアクセスするためのロックの例を示します。

補足:task.Execute()他のスレッドがタスクを並行して実行することを禁止するため、ロックを確認する必要があります。それはあなたが達成したいことかもしれませんが、この場合 ConcurrentDictionary を使用するのはやり過ぎかもしれません。

于 2012-05-09T01:35:33.520 に答える