using System.Threading.Tasks;
public static void Main()
var processTimeSpan = TimeSpan.FromSeconds(1);
var waitTimeSpan = Timeout.InfiniteTimeSpan;
Worker worker = new Worker();
new Thread(async () => await worker.Run(0, processTimeSpan, waitTimeSpan)).Start();
new Thread(async () => await worker.Run(1, processTimeSpan, waitTimeSpan)).Start();
new Thread(async () => await worker.Run(2, processTimeSpan, waitTimeSpan)).Start();
new Thread(async () => await worker.Run(3, processTimeSpan, waitTimeSpan)).Start();
Thread.Sleep(TimeSpan.FromSeconds(7));
Console.WriteLine("Done");
private readonly SemaphoreSlim _semaphoreSlim;
_semaphoreSlim = new SemaphoreSlim(1, 1);
public async Task Run(int id, TimeSpan processTimeSpan, TimeSpan waitTimeSpan)
Console.WriteLine(id + " start wait");
await _semaphoreSlim.WaitAsync(waitTimeSpan);
Console.WriteLine(id + " end wait");
Console.WriteLine(id + " start process");
Thread.Sleep(processTimeSpan);
Console.WriteLine(id + " end process");
Console.WriteLine(id + " start semaphore release");
_semaphoreSlim.Release();
Console.WriteLine(id + " end semaphore release");