<PackageReference Include="NUnit" Version="3.0.1" />

WorkItemQueue

public class WorkItemQueue
A WorkItemQueue holds work items that are ready to be run, either initially or after some dependency has been satisfied.
using System.Collections.Generic; using System.Threading; namespace NUnit.Framework.Internal.Execution { public class WorkItemQueue { private Logger log = InternalTrace.GetLogger("WorkItemQueue"); private Queue<WorkItem> _innerQueue = new Queue<WorkItem>(); private object _syncRoot = new object(); public string Name { get; set; } public int ItemsProcessed { get; set; } public int MaxCount { get; set; } public WorkItemQueueState State { get; set; } public bool IsEmpty => _innerQueue.Count == 0; public WorkItemQueue(string name) { Name = name; State = WorkItemQueueState.Paused; MaxCount = 0; ItemsProcessed = 0; } public void Enqueue(WorkItem work) { lock (_syncRoot) { _innerQueue.Enqueue(work); if (_innerQueue.Count > MaxCount) MaxCount = _innerQueue.Count; Monitor.PulseAll(_syncRoot); } } public WorkItem Dequeue() { lock (_syncRoot) { while (IsEmpty || State != WorkItemQueueState.Running) { if (State == WorkItemQueueState.Stopped) return null; Monitor.Wait(_syncRoot); } ItemsProcessed++; return _innerQueue.Dequeue(); } } public void Start() { lock (_syncRoot) { log.Info("{0} starting", Name); State = WorkItemQueueState.Running; Monitor.PulseAll(_syncRoot); } } public void Stop() { lock (_syncRoot) { log.Info("{0} stopping - {1} WorkItems processed, max size {2}", Name, ItemsProcessed, MaxCount); State = WorkItemQueueState.Stopped; Monitor.PulseAll(_syncRoot); } } public void Pause() { lock (_syncRoot) { State = WorkItemQueueState.Paused; } } } }