Übersicht über BlockingCollection

BlockingCollection<T> ist eine threadsichere Auflistungsklasse, die die folgenden Features bietet:

  • Eine Implementierung des Producer-Consumer-Musters.

  • Gleichzeitiges Hinzufügen und Entfernen von Elementen aus mehreren Threads.

  • Optionale maximale Kapazität.

  • Einfüge- und Löschvorgänge, die blockiert werden, wenn die Auflistung leer oder voll ist.

  • „Versuchs“-Einfüge- und Löschvorgänge, die nicht oder nur für eine angegebene Zeitspanne blockiert werden.

  • Kapselt jeden Auflistungstyp, der IProducerConsumerCollection<T> implementiert.

  • Abbruch mit Abbruchtoken.

  • Zwei Arten von Enumeration mit foreach (For Each in Visual Basic):

    1. Schreibgeschützte Enumeration.

    2. Enumeration, in deren Verlauf Elemente entfernt werden.

Unterstützung von Begrenzen und Blockieren

BlockingCollection<T> unterstützt das Begrenzen und Blockieren Begrenzen bedeutet, dass Sie die maximale Kapazität der Auflistung festlegen können. Begrenzen ist in bestimmten Szenarien wichtig, da es Ihnen ermöglicht, die maximale Größe der Auflistung im Arbeitsspeicher zu steuern, und es verhindert, dass die erzeugenden Threads sich zu weit vor die verbrauchenden Threads bewegen.

Mehrere Threads oder Tasks können gleichzeitig der Auflistung Elemente hinzufügen, und wenn die Auflistung die angegebene maximale Kapazität erreicht, werden die erzeugenden Threads blockiert, bis ein Element entfernt wird. Mehrere Consumer können gleichzeitig Elemente entfernen, und wenn die Auflistung leer ist, werden die verbrauchenden Threads blockiert, bis ein Producer ein Element hinzufügt. Ein Producer-Thread kann CompleteAdding aufrufen, um anzuzeigen, dass keine Elemente mehr hinzugefügt werden. Consumer überwachen die IsCompleted-Eigenschaft, um zu wissen, wann die Auflistung leer ist, und keine Elemente mehr hinzugefügt werden. Das folgende Beispiel zeigt eine einfache BlockingCollection mit einer begrenzten Kapazität von 100. Ein Producer-Task fügt der Auflistung Elemente hinzu, solange eine externe Bedingung wahr ist, und ruft dann CompleteAdding auf. Der Consumer-Task entnimmt Elemente, bis die IsCompleted-Eigenschaft wahr ist.

[!code-csharpCDS_BlockingCollection#04] [!code-vbCDS_BlockingCollection#04]

Ein vollständiges Beispiel finden Sie unter Gewusst wie: Hinzufügen und Entfernen von einzelnen Elementen zu bzw. aus einer BlockingCollection.

Zeitgesteuerte Blockierungsvorgänge

In zeitgesteuerten TryAdd- und TryTake-Blockierungsvorgängen, die für begrenzte Sammlungen durchgeführt werden, versucht die Methode, ein Element hinzuzufügen oder zu entnehmen. Wenn ein Element verfügbar ist, wird es in die Variable eingesetzt, die durch Verweis übergeben wurde, und die Methode gibt WAHR zurück. Wenn nach einer angegebenen Timeoutfrist kein Element abgerufen wird, gibt die Methode FALSCH zurück. Der Thread ist dann vor dem erneuten Versuch, auf die Auflistung zuzugreifen, frei für andere nützliche Aufgaben. Ein Beispiel für das zeitgesteuerte Blockieren des Zugriffs ist das zweite Beispiel unter Gewusst wie: Hinzufügen und Entfernen von einzelnen Elementen zu bzw. aus einer BlockingCollection.

Abbrechen von Hinzufüge- und Nehmevorgängen

Hinzufüge- und Nehmevorgänge werden in der Regel in einer Schleife ausgeführt. Sie können eine Schleife durch die Übergabe eines CancellationToken an die TryAdd- oder TryTake-Methode abbrechen und dann den Wert der IsCancellationRequested-Eigenschaft des Tokens in jeder Iteration überprüfen. Wenn der Wert WAHR ist, liegt es an Ihnen, auf die Abbruchanforderung durch Bereinigen aller Ressourcen und Beenden der Schleife zu reagieren. Das folgende Beispiel zeigt eine Überladung von TryAdd, die ein Abbruchtoken entgegennimmt, und den Code, der es verwendet:

[!code-csharpCDS_BlockingCollection#05] [!code-vbCDS_BlockingCollection#05]

Ein Beispiel für das Hinzufügen von Abbruchunterstützung ist das zweite Beispiel unter Gewusst wie: Hinzufügen und Entfernen von einzelnen Elementen zu bzw. aus einer BlockingCollection.

Angeben des Auflistungstyps

Beim Erstellen einer BlockingCollection<T> können Sie nicht nur die begrenzte Kapazität angeben, sondern auch den Typ der zu verwendenden Auflistung. Sie könnten z.B. einen ConcurrentQueue<T> für das First-in-First-out-Verhalten (FIFO) oder einen ConcurrentStack<T> für das Last-in-First-out-Verhalten (LIFO) angeben. Sie können jede Auflistungsklasse verwenden, die die IProducerConsumerCollection<T>-Schnittstelle implementiert. Der standardmäßige Auflistungstyp für BlockingCollection<T> ist ConcurrentQueue<T>. Das folgende Codebeispiel veranschaulicht das Erstellen einer BlockingCollection<T> von Zeichenfolgen, die eine Kapazität von 1000 hat und einen ConcurrentBag<T> verwendet:

Dim bc = New BlockingCollection(Of String)(New ConcurrentBag(Of String()), 1000)  
BlockingCollection<string> bc = new BlockingCollection<string>(new ConcurrentBag<string>(), 1000 );  

Weitere Informationen finden Sie unter Gewusst wie: Hinzufügen von Begrenzungs- und Blockadefunktionen zu einer Auflistung.

IEnumerable-Unterstützung

BlockingCollection<T> bietet eine GetConsumingEnumerable-Methode, mit der Consumer eine foreach (For Each in Visual Basic) verwenden können, um Elemente zu entfernen, bis die Sammlung abgeschlossen ist, d.h. bis sie leer ist und keine Elemente mehr hinzugefügt werden. Weitere Informationen finden Sie unter Gewusst wie: Entfernen von Elementen in einer BlockingCollection mit ForEach.

Verwenden vieler BlockingCollections als eine einzige

Für Szenarien, in denen ein Consumer Elemente aus mehreren Auflistungen gleichzeitig nehmen muss, können Sie Arrays von BlockingCollection<T> erstellen und statische Methoden wie TakeFromAny und AddToAny verwenden, die Elemente beliebigen Auflistungen im Array hinzufügen bzw. daraus entnehmen. Wenn eine Auflistung blockiert wird, versucht die Methode sofort, eine andere zu verwenden, bis sie eine findet, die den Vorgang ausführen kann. Weitere Informationen finden Sie unter Gewusst wie: Verwenden von Arrays mit blockierenden Auflistungen in einer Pipeline.

Siehe auch

System.Collections.Concurrent
Auflistungen und Datenstrukturen
threadsichere Auflistungen