Skip to content

Latest commit

 

History

History
33 lines (23 loc) · 3.6 KB

how-to-use-foreach-to-remove.md

File metadata and controls

33 lines (23 loc) · 3.6 KB
description title ms.date dev_langs helpviewer_keywords ms.assetid
Learn more about: Use foreach to remove items in a BlockingCollection
Use foreach to remove items in a BlockingCollection
05/04/2020
csharp
vb
thread-safe collections, how to enumerate blocking collection
2096103c-22f7-420d-b631-f102bc33a6dd

Use foreach to remove items in a BlockingCollection

In addition to taking items from a xref:System.Collections.Concurrent.BlockingCollection%601 by using the xref:System.Collections.Concurrent.BlockingCollection%601.Take%2A and xref:System.Collections.Concurrent.BlockingCollection%601.TryTake%2A method, you can also use a foreach (For Each in Visual Basic) with the xref:System.Collections.Concurrent.BlockingCollection%601.GetConsumingEnumerable%2A?displayProperty=nameWithType to remove items until adding is completed and the collection is empty. This is called a mutating enumeration or consuming enumeration because, unlike a typical foreach (For Each) loop, this enumerator modifies the source collection by removing items.

Example

The following example shows how to remove all the items in a xref:System.Collections.Concurrent.BlockingCollection%601 by using a foreach (For Each) loop.

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

This example uses a foreach loop with the xref:System.Collections.Concurrent.BlockingCollection%601.GetConsumingEnumerable%2A?displayProperty=nameWithType method in the consuming thread, which causes each item to be removed from the collection as it is enumerated. xref:System.Collections.Concurrent.BlockingCollection%601?displayProperty=nameWithType limits the maximum number of items that are in the collection at any time. Enumerating the collection in this way blocks the consumer thread if no items are available or if the collection is empty. In this example blocking is not a concern because the producer thread adds items faster than they can be consumed.

The xref:System.Collections.Concurrent.BlockingCollection%601.GetConsumingEnumerable%2A?displayProperty=nameWithType returns an IEnumerable<T>, thus order cannot be guaranteed. However, internally a xref:System.Collections.Concurrent.ConcurrentQueue%601?displayProperty=nameWithType is used as the underlying collection type - which will dequeue objects following first-in-first-out (FIFO) ordering. If concurrent calls to xref:System.Collections.Concurrent.BlockingCollection%601.GetConsumingEnumerable%2A?displayProperty=nameWithType are made, they will compete. One item consumed (dequeued) in one enumeration cannot be observed in the other.

To enumerate the collection without modifying it, just use foreach (For Each) without the xref:System.Collections.Concurrent.BlockingCollection%601.GetConsumingEnumerable%2A method. However, it is important to understand that this kind of enumeration represents a snapshot of the collection at a precise point in time. If other threads are adding or removing items concurrently while you are executing the loop, then the loop might not represent the actual state of the collection.

See also