using System.Threading.Tasks;
private static SemaphoreSlim semaphore;
private static int padding;
public static void Main()
semaphore = new SemaphoreSlim(0, 3);
var throttler = new Throttler(semaphore);
Console.WriteLine("{0} tasks can enter the semaphore.", semaphore.CurrentCount);
Task[] tasks = new Task[5];
for (int i = 0; i <= 4; i++)
tasks[i] = Task.Run(() =>
RunTask(throttler, semaphore);
Console.Write("Main thread calls Release(3) --> ");
Console.WriteLine("{0} tasks can enter the semaphore.", semaphore.CurrentCount);
Console.WriteLine("Main thread exits.");
static void RunTask(Throttler throttler, SemaphoreSlim semaphore)
using (throttler.RentAsync())
Interlocked.Add(ref padding, 100);
Thread.Sleep(1000 + padding);
private SemaphoreSlim _Semaphore;
public Throttler(SemaphoreSlim semaphore)
public Holder RentAsync()
Console.WriteLine("Task {0} begins and waits for the semaphore.", Task.CurrentId);
Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId);
return new Holder(_Semaphore);
public class Holder : IDisposable
private SemaphoreSlim _Semaphore;
public Holder(SemaphoreSlim semaphore)
int semaphoreCount = _Semaphore.CurrentCount;
Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.", Task.CurrentId, semaphoreCount);