SemaphoreSlim Class

Namespace: System.Threading

Assembly: System.Runtime.dll

Summary

Inheritance ObjectWaitHandleSemaphoreSlim
Derived classes None
Implements IDisposable

Represents a System.Threading.WaitHandle that limits the number of threads that can access a resource concurrently.

Constructors

SemaphoreSlim (Int32)

Initializes a new instance of the SemaphoreSlim class with the specified initial number of entries.

public SemaphoreSlim(int initialCount);

Parameters

  • initialCount: The number of entries to allow initially.

SemaphoreSlim (Int32, Int32)

Initializes a new instance of the SemaphoreSlim class with the specified initial and maximum number of entries.

public SemaphoreSlim(int initialCount, int maxCount);

Parameters

  • initialCount: The number of entries to allow initially.
  • maxCount: The maximum number of entries that can be accessed concurrently.

Methods

Wait (Int32)

Decrements the current thread's semaphore count, blocking if necessary until an entry is available.

public void Wait(int millisecondsTimeout);

Parameters

  • millisecondsTimeout: The number of milliseconds to wait, or -1 to wait indefinitely.

Return Value

true if the semaphore was released before the timeout expired; otherwise, false.

Wait

Decrements the current thread's semaphore count, blocking indefinitely until an entry is available.

public void Wait();

Release (Int32)

Increments the semaphore count, releasing the specified number of waiting threads.

public int Release(int releaseCount);

Parameters

  • releaseCount: The number of entries to release.

Return Value

The previous count of the semaphore.

Release

Increments the semaphore count, releasing one waiting thread.

public int Release();

Return Value

The previous count of the semaphore.

WaitAsync (Int32)

Asynchronously decrements the current thread's semaphore count, blocking if necessary until an entry is available.

public System.Threading.Tasks.Task<bool> WaitAsync(int millisecondsTimeout);

Parameters

  • millisecondsTimeout: The number of milliseconds to wait, or -1 to wait indefinitely.

Return Value

A task that represents the asynchronous operation. The value of the TResult parameter is true if the semaphore was released before the timeout expired; otherwise, false.

WaitAsync

Asynchronously decrements the current thread's semaphore count, blocking indefinitely until an entry is available.

public System.Threading.Tasks.Task<bool> WaitAsync();

Return Value

A task that represents the asynchronous operation. The value of the TResult parameter is always true.

Exceptions

Remarks

A SemaphoreSlim is a lightweight semaphore that can be used for synchronization within a single process. It is more efficient than System.Threading.Semaphore because it does not rely on operating system synchronization primitives.

Use the Wait or WaitAsync methods to enter the semaphore. If the semaphore's current count is greater than zero, the method decrements the count and returns immediately. If the current count is zero, the method blocks until the semaphore is released or the timeout expires.

Use the Release method to increment the semaphore's count, potentially allowing waiting threads to proceed.

It is important to always call Release when you are finished with the resource protected by the semaphore. Failure to do so can lead to deadlocks.

Example

using System;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
    private static SemaphoreSlim _semaphore = new SemaphoreSlim(3); // Allow 3 concurrent operations

    public static async Task Main(string[] args)
    {
        var tasks = new List<Task>();

        for (int i = 1; i <= 5; i++)
        {
            int taskId = i;
            tasks.Add(Task.Run(async () =>
            {
                Console.WriteLine($"Task {taskId} is waiting to enter.");
                await _semaphore.WaitAsync();
                try
                {
                    Console.WriteLine($"Task {taskId} has entered the semaphore.");
                    await Task.Delay(TimeSpan.FromSeconds(2)); // Simulate work
                    Console.WriteLine($"Task {taskId} is leaving the semaphore.");
                }
                finally
                {
                    _semaphore.Release();
                }
            }));
        }

        await Task.WhenAll(tasks);
        Console.WriteLine("All tasks completed.");
    }
}