System.Collections.Concurrent名前空間には、スレッド セーフでスケーラブルなコレクション クラスがいくつか含まれています。 複数のスレッドは、ユーザー コードで追加の同期を必要とせずに、これらのコレクションの項目を安全かつ効率的に追加または削除できます。 新しいコードを記述するときは、同時実行コレクション クラスを使用して、複数のスレッドをコレクションに同時に書き込みます。 共有コレクションからのみ読み取る場合は、 System.Collections.Generic 名前空間のクラスを使用できます。
System.Collections と System.Collections.Generic
System.Collections名前空間のコレクション クラスには、ArrayListとHashtableが含まれます。 これらのクラスは、Synchronized
プロパティを通じて一部のスレッド セーフティを提供し、コレクションのスレッド セーフ ラッパーを返します。 ラッパーは、すべての追加または削除操作でコレクション全体をロックすることによって機能します。 したがって、コレクションにアクセスしようとしている各スレッドは、その順番が 1 つのロックを受け取るのを待つ必要があります。 このプロセスはスケーラブルではなく、大規模なコレクションのパフォーマンスが大幅に低下する可能性があります。 さらに、設計は競合状態から保護されません。 詳細については、「 ジェネリック コレクションでの同期」を参照してください。
System.Collections.Generic名前空間のコレクション クラスには、List<T>とDictionary<TKey,TValue>が含まれます。 これらのクラスは、 System.Collections クラスと比較して、型の安全性とパフォーマンスを向上させます。 ただし、 System.Collections.Generic クラスはスレッド同期を提供しません。複数のスレッドでアイテムが同時に追加または削除されるときに、ユーザー コードはすべての同期を提供する必要があります。
System.Collections.Concurrent名前空間で同時実行コレクション クラスを使用することをお勧めします。これは、型の安全性と、より効率的で完全なスレッド セーフを提供するためです。
きめ細かいロックとロックフリーメカニズム
一部の同時実行コレクションの種類では、 SpinLock、 SpinWait、 SemaphoreSlim、 CountdownEventなどの軽量の同期メカニズムを使用します。 これらの同期型では、通常、スレッドを実際の 状態にする前の短期間にWait
が使用されます。 待機時間が短いと予想される場合、スピンは待機よりも計算コストがはるかに低くなります。これには、高価なカーネル遷移が伴います。 スピンを使用するコレクション クラスの場合、この効率は、複数のスレッドが項目を高いレートで追加および削除できることを意味します。 スピンとブロッキングの詳細については、「SpinLock」および「SpinWait」を参照してください。
ConcurrentQueue<T>クラスとConcurrentStack<T> クラスでは、ロックはまったく使用されません。 代わりに、スレッド セーフを実現するために、 Interlocked 操作に依存します。
注
同時実行コレクション クラスは ICollectionをサポートするため、これらのプロパティは無関係であっても、 IsSynchronized プロパティと SyncRoot プロパティの実装を提供します。 IsSynchronized
は常に false
を返し、 SyncRoot
は常に null
されます (Visual Basic ではNothing
)。
次の表に、 System.Collections.Concurrent 名前空間のコレクション型を示します。
タイプ | 説明 |
---|---|
BlockingCollection<T> | IProducerConsumerCollection<T>を実装する任意の型に対して、境界処理機能とブロック処理機能を提供します。 詳細については、「 BlockingCollection の概要」を参照してください。 |
ConcurrentDictionary<TKey,TValue> | キーと値のペアのディクショナリのスレッド セーフな実装。 |
ConcurrentQueue<T> | スレッドセーフなFIFO(先入れ先出し)キューの実装。 |
ConcurrentStack<T> | LIFO (最後に入って、最初に出る) スタックのスレッドセーフな実装。 |
ConcurrentBag<T> | 順序指定されていない要素のコレクションのスレッド セーフな実装。 |
IProducerConsumerCollection<T> | BlockingCollection で使用するために型が実装する必要があるインターフェイス。 |
関連資料
タイトル | 説明 |
---|---|
BlockingCollection の概要 | BlockingCollection<T>型によって提供される機能について説明します。 |
方法: ConcurrentDictionary から項目を追加および削除する | 要素を追加および削除する方法について説明します。 ConcurrentDictionary<TKey,TValue> |
方法: BlockingCollection から項目を個別に追加および取得する | 読み取り専用列挙子を使用せずに、ブロックコレクションから項目を追加および取得する方法について説明します。 |
方法: 境界機能とブロック機能をコレクションに追加する | IProducerConsumerCollection<T> コレクションの基になるストレージ メカニズムとしてコレクション クラスを使用する方法について説明します。 |
方法: ForEach を使用して BlockingCollection 内の項目を削除する | foreach (Visual Basic ではFor Each ) を使用して、ブロックしているコレクション内のすべての項目を削除する方法について説明します。 |
方法: パイプラインでブロッキング コレクションの配列を使用する | 複数のブロック コレクションを同時に使用してパイプラインを実装する方法について説明します。 |
方法: ConcurrentBag を使用してオブジェクト プールを作成する | 同時実行バッグを使用して、新しいオブジェクトを継続的に作成するのではなく、オブジェクトを再利用できるシナリオでパフォーマンスを向上させる方法を示します。 |
リファレンス
.NET