final class · System.Threading

BlockingCollection<T>

public final class BlockingCollection<T>

A queue that hands items from producers to consumers: Take waits for an item; after CompleteAdding, Take on an empty queue throws and TryTake gives false.

Tipo
final class
Espacio de nombres
System.Threading
Ensamblado
System.Core
Acceso
public, final
Archivo fuente
Threading.ant

Parámetros de tipo

NombreRestricciones
Tcualquier tipo

Herencia

Clases base
Any BlockingCollection<T>

Constructores

new()
#

Propiedades

bool IsAddingCompleted { get; }
#

read-only

bool IsCompleted { get; }
#

read-only

i32 Count { get; }
#

read-only

Métodos

Add(T item)
#
Take() : T
#

The next item (waiting for one).

WaitForItem() : bool
#

Whether an item can be taken (waiting for one, unless adding is complete); then Take gives it at once to this consumer only if no other one takes it first.

CompleteAdding()
#
Dispose()
#

Frees what it holds (it must not be used after).

Miembros privados e internos (5)

Mutex mutex
#

private

Condition changed
#

private

Queue<T> items
#

private

bool completed
#

private

i32 waiters
#

private

Miembros heredados (5)

Código fuente

BlockingCollection<T> en Antril, descompilado a partir de su Larva HIR.

System.Threading.BlockingCollection.ant
// System.Threading.BlockingCollection — System.Core (decompiled from Larva HIR)

import System;

into namespace System.Threading
{
	/// A queue that hands items from producers to consumers: Take waits for an item; after CompleteAdding, Take on an
	/// empty queue throws and TryTake gives false.
	public final class BlockingCollection<T>
	{
		Mutex mutex;
		Condition changed;
		Queue<T> items;
		bool completed;
		i32 waiters;

		public:
			new()
			{
				mutex = new Mutex();
				changed = new Condition();
				items = new Queue<T>();
			}

			Add(T item)
			{
				mutex.Lock();
				if (completed)
				{
					mutex.Unlock();
					throw new InvalidOperationError("BlockingCollection: adding is complete");
				}
				items.Enqueue(item);
				bool wake = waiters > 0;
				mutex.Unlock();
				if (wake)
					changed.Signal();
			}

			/// The next item (waiting for one).
			Take() : T
			{
				mutex.Lock();
				loop (items.Count == 0)
				{
					if (completed)
					{
						mutex.Unlock();
						throw new InvalidOperationError("BlockingCollection: empty and adding is complete");
					}
					waiters++;
					changed.Wait(mutex);
					waiters--;
				}
				T item = items.Dequeue();
				mutex.Unlock();
				return item;
			}

			/// Whether an item can be taken (waiting for one, unless adding is complete); then Take gives it at once to
			/// this consumer only if no other one takes it first.
			WaitForItem() : bool
			{
				mutex.Lock();
				loop (items.Count == 0 && !completed)
				{
					waiters++;
					changed.Wait(mutex);
					waiters--;
				}
				bool any = items.Count > 0;
				mutex.Unlock();
				return any;
			}

			CompleteAdding()
			{
				mutex.Lock();
				completed = true;
				mutex.Unlock();
				changed.Broadcast();
			}

			/// Frees what it holds (it must not be used after).
			Dispose()
			{
				mutex.Dispose();
				changed.Dispose();
			}

			bool IsAddingCompleted
			{
				get => completed;
			}

			bool IsCompleted
			{
				get
				{
					mutex.Lock();
					bool done = completed && items.Count == 0;
					mutex.Unlock();
					return done;
				}
			}

			i32 Count
			{
				get => items.Count;
			}
	}
}
Esc