using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class FifoCriticalSection : IDisposable
private readonly FifoMonitor _parent;
public FifoCriticalSection(FifoMonitor parent)
private object _innerLock = new object();
private volatile int counter = 0;
private volatile int current = 1;
public FifoCriticalSection Lock()
return new FifoCriticalSection(this);
int mine = Interlocked.Increment(ref counter);
Monitor.Enter(_innerLock);
while (current != mine) Monitor.Wait(_innerLock);
Interlocked.Increment(ref current);
Monitor.PulseAll(_innerLock);
Monitor.Exit(_innerLock);
public class QueuedBlockingCollection<T> : BlockingCollection<T>
private FifoMonitor monitor = new FifoMonitor();
public QueuedBlockingCollection(int max) : base (max) {}
public void Enqueue(T item)
public static void Main()
var blockingCollection = new QueuedBlockingCollection<int>(10);
var tasks = new Task[10];
for (int i=1; i<=10; i++) blockingCollection.Add(99);
for (int i=1; i<=10; i++)
tasks[index-1] = Task.Run( () => blockingCollection.Enqueue(index) );
while (blockingCollection.Count > 0)
var n = blockingCollection.Take();
while (blockingCollection.Count > 0)
var n = blockingCollection.Take();