Semaphore Threading in C# with Code Example

Semaphore is a programming construct used to set the limit on number of threads that can have access to a critical section. A critical section is a data structure or a device which is shared by different threads but only one thread can access it at a time. An example scenario is, when you want to restrict simultaneous access to database connection code to a fixed number of threads, so that the number of connections to database at any given time is within a certain limit.

System.Threading.Semaphore type in Sytem.dll assembly provides mechanism to achieve this.

First step in using Semaphore class is to create an instance of Semaphore object, first parameter is the number of slots available for other threads and second parameter is the maximum number of slots available. When you want to reserve some slots for the calling thread, decrease the first parameter by the number of slots you want to reserve for the calling thread.

When a thread is entering the critical section it calls WaitOne() and after exiting the critical section it calls Release(). Semaphore count is decremented when a thread enters critical section (WaitOne()) and incremented when the thread exits the critical section (Release()). When count becomes zero, subsequent threads will be blocked until other threads release the semaphore.

Below sample shows the use of Semaphore. The output of the sample is random as the order in which the blocked threads enter the Semaphore (Critical section) is random.

using System;
using System.Threading;

namespace CSharp_Samples
    public class SemaphoreSample
        // Creates a semaphore object that can support maximum of 4 concurrent 
        // requests. Initial count is set to 3, so only 3 slots available
        // for other threads and 1 slot is reserved for current thread.
        static Semaphore semaphoreObject = new Semaphore(3, 4);

        private static void DoWork()
            Console.WriteLine("{0} is waiting in QUEUE...", Thread.CurrentThread.Name);

            // Thread waits to get an available slot

            Console.WriteLine("{0} enters the Critical Section!", Thread.CurrentThread.Name);

            // Simulate work by waiting for 1 second.

            Console.WriteLine("{0} is leaving the Critical Section", Thread.CurrentThread.Name);

            // Release the slot.

        public static void Main()
            // Create 10 threads, Set their name property 
            // and start DoWork on each thread.
            for (int i = 0; i < 10; i++)
                Thread thread = new Thread(DoWork);
                thread.Name = "Thread_" + i;