Export (0) Print
Expand All

SemaphoreSlim Class

Represents a lightweight alternative to Semaphore that limits the number of threads that can access a resource or pool of resources concurrently.

System.Object
  System.Threading.SemaphoreSlim

Namespace:  System.Threading
Assembly:  mscorlib (in mscorlib.dll)

[ComVisibleAttribute(false)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
	ExternalThreading = true)]
public class SemaphoreSlim : IDisposable

The SemaphoreSlim type exposes the following members.

  NameDescription
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsSemaphoreSlim(Int32)Initializes a new instance of the SemaphoreSlim class, specifying the initial number of requests that can be granted concurrently.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsSemaphoreSlim(Int32, Int32)Initializes a new instance of the SemaphoreSlim class, specifying the initial and maximum number of requests that can be granted concurrently.
Top

  NameDescription
Public propertySupported by Portable Class LibrarySupported in .NET for Windows Store appsAvailableWaitHandleReturns a WaitHandle that can be used to wait on the semaphore.
Public propertySupported by Portable Class LibrarySupported in .NET for Windows Store appsCurrentCountGets the number of remaining threads that can enter the SemaphoreSlim object.
Top

  NameDescription
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsDispose()Releases all resources used by the current instance of the SemaphoreSlim class.
Protected methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsDispose(Boolean)Releases the unmanaged resources used by the SemaphoreSlim, and optionally releases the managed resources.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsEquals(Object)Determines whether the specified object is equal to the current object. (Inherited from Object.)
Protected methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsFinalizeAllows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.)
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetHashCodeServes as the default hash function. (Inherited from Object.)
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetTypeGets the Type of the current instance. (Inherited from Object.)
Protected methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsMemberwiseCloneCreates a shallow copy of the current Object. (Inherited from Object.)
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsRelease()Releases the SemaphoreSlim object once.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsRelease(Int32)Releases the SemaphoreSlim object a specified number of times.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsToStringReturns a string that represents the current object. (Inherited from Object.)
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsWait()Blocks the current thread until it can enter the SemaphoreSlim.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsWait(CancellationToken)Blocks the current thread until it can enter the SemaphoreSlim, while observing a CancellationToken.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsWait(Int32)Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsWait(TimeSpan)Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan to specify the timeout.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsWait(Int32, CancellationToken)Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout, while observing a CancellationToken.
Public methodSupported by Portable Class LibrarySupported in .NET for Windows Store appsWait(TimeSpan, CancellationToken)Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan that specifies the timeout, while observing a CancellationToken.
Public methodSupported in .NET for Windows Store appsWaitAsync()Asynchronously waits to enter the SemaphoreSlim.
Public methodSupported in .NET for Windows Store appsWaitAsync(CancellationToken)Asynchronously waits to enter the SemaphoreSlim, while observing a CancellationToken.
Public methodSupported in .NET for Windows Store appsWaitAsync(Int32)Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval.
Public methodSupported in .NET for Windows Store appsWaitAsync(TimeSpan)Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval.
Public methodSupported in .NET for Windows Store appsWaitAsync(Int32, CancellationToken)Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval, while observing a CancellationToken.
Public methodSupported in .NET for Windows Store appsWaitAsync(TimeSpan, CancellationToken)Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval, while observing a CancellationToken.
Top

Semaphores are of two types: local semaphores and named system semaphores. The former is local to an app. The latter is visible throughout the operating system and is suitable for inter-process synchronization. The SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores. Unlike the Semaphore class, the SemaphoreSlim class doesn’t support named system semaphores. You can use it as a local semaphore only. The SemaphoreSlim class is the recommended semaphore for synchronization within a single app.

A lightweight semaphore controls access to a pool of resources that is local to your application. When you instantiate a semaphore, you can specify the maximum number of threads that can enter the semaphore concurrently. You also specify the initial number of threads that can enter the semaphore concurrently. This defines the semaphore's count.

The count is decremented each time a thread enters the semaphore, and incremented each time a thread releases the semaphore. To enter the semaphore, a thread calls one of the Wait or WaitAsync overloads. To release the semaphore, it calls one of the Release overloads. When the count reaches zero, subsequent calls to one of the Wait methods block until other threads release the semaphore. If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

The basic structure for code that uses a semaphore to protect resources is:

' Enter semaphore by calling one of the Wait or WaitAsync methods.
SemaphoreSlim.Wait()
' 
' Execute code protected by the semaphore. 
'
SemaphoreSlim.Release()

When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created. The semaphore's count is available from the CurrentCount property.

Important noteImportant

The SemaphoreSlim class doesn’t enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods. In addition, if the SemaphoreSlim(Int32) constructor is used to instantiate the SemaphoreSlim object, the CurrentCount property can increase beyond the value set by the constructor. It is the programmer's responsibility to ensure that calls to Wait or WaitAsync methods are appropriately paired with calls to Release methods.

NoteNote

The HostProtectionAttribute attribute applied to this type or member has the following Resources property value: Synchronization | ExternalThreading. The HostProtectionAttribute does not affect desktop applications (which are typically started by double-clicking an icon, typing a command, or entering a URL in a browser). For more information, see the HostProtectionAttribute class or SQL Server Programming and Host Protection Attributes.

The following example creates a semaphore with a maximum count of three threads and an initial count of zero threads. The example starts five tasks, all of which block waiting for the semaphore. The main thread calls the Release(Int32) overload to increase the semaphore count to its maximum, which allows three tasks to enter the semaphore. Each time the semaphore is released, the previous semaphore count is displayed. Console messages track semaphore use. The simulated work interval is increased slightly for each thread to make the output easier to read.

Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Private semaphore As SemaphoreSlim
    ' A padding interval to make the output more orderly. 
    Private padding As Integer 

   Public Sub Main()
      ' Create the semaphore.
      semaphore = New SemaphoreSlim(0, 3)
      Console.WriteLine("{0} tasks can enter the semaphore.",
                        semaphore.CurrentCount)
      Dim tasks(4) As Task

      ' Create and start five numbered tasks. 
      For i As Integer = 0 To 4
         tasks(i) = Task.Run(
            Sub()
               ' Each task begins by requesting the semaphore.
               Console.WriteLine("Task {0} begins and waits for the semaphore.",
                              Task.CurrentId)
               semaphore.Wait()

               padding = Interlocked.Add(padding, 100)

               Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId)

               ' The task just sleeps for 1+ seconds.
               Thread.Sleep(1000 + padding)

               Console.WriteLine("Task {0} releases the semaphore previous count: {1}.",
                                 Task.CurrentId, semaphore.Release())
            End Sub )
      Next 

      ' Wait for half a second, to allow all the tasks to start and block.
      Thread.Sleep(500)

      ' Restore the semaphore count to its maximum value.
      Console.Write("Main thread calls Release(3) --> ")
      semaphore.Release(3)
      Console.WriteLine("{0} tasks can enter the semaphore.",
                        semaphore.CurrentCount)
      ' Main thread waits for the tasks to complete.
      Task.WaitAll(tasks)

      Console.WriteLine("Main thread exits.")
   End Sub 
End Module 
' The example displays output like the following: 
'       0 tasks can enter the semaphore. 
'       Task 1 begins and waits for the semaphore. 
'       Task 5 begins and waits for the semaphore. 
'       Task 2 begins and waits for the semaphore. 
'       Task 4 begins and waits for the semaphore. 
'       Task 3 begins and waits for the semaphore. 
'       Main thread calls Release(3) --> 3 tasks can enter the semaphore. 
'       Task 4 enters the semaphore. 
'       Task 1 enters the semaphore. 
'       Task 3 enters the semaphore. 
'       Task 4 releases the semaphore; previous count: 0. 
'       Task 2 enters the semaphore. 
'       Task 1 releases the semaphore; previous count: 0. 
'       Task 3 releases the semaphore; previous count: 0. 
'       Task 5 enters the semaphore. 
'       Task 2 releases the semaphore; previous count: 1. 
'       Task 5 releases the semaphore; previous count: 2. 
'       Main thread exits.

.NET Framework

Supported in: 4.5, 4

.NET Framework Client Profile

Supported in: 4

Portable Class Library

Supported in: Portable Class Library

.NET for Windows Store apps

Supported in: Windows 8

.NET for Windows Phone apps

Supported in: Windows Phone 8.1, Windows Phone Silverlight 8.1, Windows Phone Silverlight 8

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

All public and protected members of SemaphoreSlim are thread-safe and may be used concurrently from multiple threads, with the exception of Dispose, which must be used only when all other operations on the SemaphoreSlim have completed.

Show:
© 2014 Microsoft