using System.Threading.Tasks;
using System.Collections.Concurrent;
public static async Task Main()
var q = new SemaphoreQueue(1,1);
var tasks = Enumerable.Range(0,5).Select(i => Start(q, i));
await Task.WhenAll(tasks);
Console.WriteLine("Done");
public static async Task Start(SemaphoreQueue q, int i)
var t = new Random().Next(100);
Console.WriteLine($"Starting {i}");
Console.WriteLine($"Started {i}");
public class SemaphoreQueue
private SemaphoreSlim semaphore;
private ConcurrentQueue<TaskCompletionSource<bool>> queue =
new ConcurrentQueue<TaskCompletionSource<bool>>();
public SemaphoreQueue(int initialCount)
semaphore = new SemaphoreSlim(initialCount);
public SemaphoreQueue(int initialCount, int maxCount)
semaphore = new SemaphoreSlim(initialCount, maxCount);
var tcs = new TaskCompletionSource<bool>();
semaphore.WaitAsync().ContinueWith(t =>
TaskCompletionSource<bool> popped;
if (queue.TryDequeue(out popped))