SemaphoreSlim SemaphoreSlim SemaphoreSlim SemaphoreSlim Class

Definición

Representa una alternativa ligera a Semaphore que limita el número de subprocesos que pueden tener acceso a un recurso o grupo de recursos simultáneamente.Represents a lightweight alternative to Semaphore that limits the number of threads that can access a resource or pool of resources concurrently.

public ref class SemaphoreSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class SemaphoreSlim : IDisposable
type SemaphoreSlim = class
    interface IDisposable
Public Class SemaphoreSlim
Implements IDisposable
Herencia
SemaphoreSlimSemaphoreSlimSemaphoreSlimSemaphoreSlim
Atributos
Implementaciones

Ejemplos

En el ejemplo siguiente se crea un semáforo con un recuento máximo de tres subprocesos y un recuento inicial de cero.The following example creates a semaphore with a maximum count of three threads and an initial count of zero threads. En el ejemplo se inician cinco tareas, todas las cuales bloquean la espera del semáforo.The example starts five tasks, all of which block waiting for the semaphore. El subproceso principal llama Release(Int32) a la sobrecarga para aumentar el recuento del semáforo a su máximo, lo que permite que tres tareas entren en el semáforo.The main thread calls the Release(Int32) overload to increase the semaphore count to its maximum, which allows three tasks to enter the semaphore. Cada vez que se libera el semáforo, se muestra el recuento de semáforos anterior.Each time the semaphore is released, the previous semaphore count is displayed. Seguimiento de mensajes de la consola use.Console messages track semaphore use. El intervalo de trabajo simulado aumenta ligeramente en cada subproceso para que la salida sea más fácil de leer.The simulated work interval is increased slightly for each thread to make the output easier to read.

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

public class Example
{
    private static SemaphoreSlim semaphore;
    // A padding interval to make the output more orderly.
    private static int padding;

    public static void Main()
    {
        // Create the semaphore.
        semaphore = new SemaphoreSlim(0, 3);
        Console.WriteLine("{0} tasks can enter the semaphore.",
                          semaphore.CurrentCount);
        Task[] tasks = new Task[5];
        
        // Create and start five numbered tasks.
        for(int i = 0; i <= 4; i++)
        {
            tasks[i] = Task.Run( () => {
            // Each task begins by requesting the semaphore.
            Console.WriteLine("Task {0} begins and waits for the semaphore.",
                              Task.CurrentId);
            semaphore.Wait();

            Interlocked.Add(ref 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()); } );
        }

        // 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.");
    }
}
// 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.
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()

               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.

Comentarios

Los semáforos son de dos tipos: semáforos locales y semáforos de sistema con nombre.Semaphores are of two types: local semaphores and named system semaphores. El primero es local para una aplicación.The former is local to an app. El último es visible en todo el sistema operativo y es adecuado para la sincronización entre procesos.The latter is visible throughout the operating system and is suitable for inter-process synchronization. Es una alternativa ligera a la Semaphore clase que no usa semáforos del kernel de Windows. SemaphoreSlimThe SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores. A diferencia de Semaphore la clase, SemaphoreSlim la clase no admite semáforos de sistema con nombre.Unlike the Semaphore class, the SemaphoreSlim class doesn't support named system semaphores. Solo se puede usar como semáforo local.You can use it as a local semaphore only. La SemaphoreSlim clase es el semáforo recomendado para la sincronización dentro de una sola aplicación.The SemaphoreSlim class is the recommended semaphore for synchronization within a single app.

Un semáforo ligero controla el acceso a un grupo de recursos que es local para la aplicación.A lightweight semaphore controls access to a pool of resources that is local to your application. Al crear una instancia de un semáforo, puede especificar el número máximo de subprocesos que pueden entrar en el semáforo simultáneamente.When you instantiate a semaphore, you can specify the maximum number of threads that can enter the semaphore concurrently. También se especifica el número inicial de subprocesos que pueden entrar en el semáforo simultáneamente.You also specify the initial number of threads that can enter the semaphore concurrently. Esto define el recuento del semáforo.This defines the semaphore's count.

El recuento se reduce cada vez que un subproceso entra en el semáforo y se incrementa cada vez que un subproceso libera el semáforo.The count is decremented each time a thread enters the semaphore, and incremented each time a thread releases the semaphore. Para entrar en el semáforo, un subproceso llama a una Wait de WaitAsync las sobrecargas o.To enter the semaphore, a thread calls one of the Wait or WaitAsync overloads. Para liberar el semáforo, llama a una de las Release sobrecargas.To release the semaphore, it calls one of the Release overloads. Cuando el número llega a cero, las llamadas subsiguientes Wait a uno de los métodos se bloquean hasta que otros subprocesos liberan el semáforo.When the count reaches zero, subsequent calls to one of the Wait methods block until other threads release the semaphore. Si se bloquean varios subprocesos, no hay ningún orden garantizado, como FIFO o LIFO, que controla cuándo los subprocesos entran en el semáforo.If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

La estructura básica del código que utiliza un semáforo para proteger los recursos es: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()  
  

Cuando todos los subprocesos han liberado el semáforo, el recuento está en el valor máximo especificado cuando se creó el semáforo.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created. El recuento del semáforo está disponible en la CurrentCount propiedad.The semaphore's count is available from the CurrentCount property.

Importante

La SemaphoreSlim clase no impone la identidad de subprocesos o tareas Waiten las llamadas Release a los métodos, WaitAsyncy.The SemaphoreSlim class doesn't enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods. Además, si se utiliza SemaphoreSlim(Int32) el constructor para crear una instancia del SemaphoreSlim objeto, la CurrentCount propiedad puede aumentar más allá del valor establecido por el constructor.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. Es responsabilidad del programador asegurarse de que las llamadas a Wait los métodos o WaitAsync se emparejan adecuadamente con las llamadas a Release los métodos.It is the programmer's responsibility to ensure that calls to Wait or WaitAsync methods are appropriately paired with calls to Release methods.

Constructores

SemaphoreSlim(Int32) SemaphoreSlim(Int32) SemaphoreSlim(Int32) SemaphoreSlim(Int32)

Inicializa una nueva instancia de la clase SemaphoreSlim, especificando el número inicial de solicitudes que se pueden conceder simultáneamente.Initializes a new instance of the SemaphoreSlim class, specifying the initial number of requests that can be granted concurrently.

SemaphoreSlim(Int32, Int32) SemaphoreSlim(Int32, Int32) SemaphoreSlim(Int32, Int32) SemaphoreSlim(Int32, Int32)

Inicializa una nueva instancia de la clase SemaphoreSlim, especificando el número inicial y máximo de solicitudes que se pueden conceder simultáneamente.Initializes a new instance of the SemaphoreSlim class, specifying the initial and maximum number of requests that can be granted concurrently.

Propiedades

AvailableWaitHandle AvailableWaitHandle AvailableWaitHandle AvailableWaitHandle

Devuelve un objeto WaitHandle que se puede usar para esperar en el semáforo.Returns a WaitHandle that can be used to wait on the semaphore.

CurrentCount CurrentCount CurrentCount CurrentCount

Obtiene el número de subprocesos restantes que puede introducir el objeto SemaphoreSlim.Gets the number of remaining threads that can enter the SemaphoreSlim object.

Métodos

Dispose() Dispose() Dispose() Dispose()

Libera todos los recursos usados por la instancia actual de la clase SemaphoreSlim.Releases all resources used by the current instance of the SemaphoreSlim class.

Dispose(Boolean) Dispose(Boolean) Dispose(Boolean) Dispose(Boolean)

Libera los recursos no administrados utilizados por el objeto SemaphoreSlim y, de forma opcional, libera los recursos administrados.Releases the unmanaged resources used by the SemaphoreSlim, and optionally releases the managed resources.

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

Determina si el objeto especificado es igual al objeto actual.Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

Sirve como la función hash predeterminada.Serves as the default hash function.

(Inherited from Object)
GetType() GetType() GetType() GetType()

Obtiene el Type de la instancia actual.Gets the Type of the current instance.

(Inherited from Object)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

Crea una copia superficial del objeto Object actual.Creates a shallow copy of the current Object.

(Inherited from Object)
Release() Release() Release() Release()

Libera una vez el objeto SemaphoreSlim.Releases the SemaphoreSlim object once.

Release(Int32) Release(Int32) Release(Int32) Release(Int32)

Libera el objeto SemaphoreSlim el número de veces especificado.Releases the SemaphoreSlim object a specified number of times.

ToString() ToString() ToString() ToString()

Devuelve una cadena que representa el objeto actual.Returns a string that represents the current object.

(Inherited from Object)
Wait() Wait() Wait() Wait()

Bloquea el subproceso actual hasta que pueda entrar en SemaphoreSlim.Blocks the current thread until it can enter the SemaphoreSlim.

Wait(CancellationToken) Wait(CancellationToken) Wait(CancellationToken) Wait(CancellationToken)

Bloquea el subproceso actual hasta que pueda entrar en SemaphoreSlim, mientras se observa un token CancellationToken.Blocks the current thread until it can enter the SemaphoreSlim, while observing a CancellationToken.

Wait(Int32) Wait(Int32) Wait(Int32) Wait(Int32)

Bloquea el subproceso actual hasta que pueda entrar en SemaphoreSlim, usando un entero de 32 bits con signo que especifica el tiempo de espera.Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout.

Wait(Int32, CancellationToken) Wait(Int32, CancellationToken) Wait(Int32, CancellationToken) Wait(Int32, CancellationToken)

Bloquea el subproceso actual hasta que pueda entrar en SemaphoreSlim, usando un entero de 32 bits con signo que especifica el tiempo de espera mientras se observa un token 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.

Wait(TimeSpan) Wait(TimeSpan) Wait(TimeSpan) Wait(TimeSpan)

Bloquea el subproceso actual hasta que pueda entrar en SemaphoreSlim, usando TimeSpan para especificar el tiempo de espera.Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan to specify the timeout.

Wait(TimeSpan, CancellationToken) Wait(TimeSpan, CancellationToken) Wait(TimeSpan, CancellationToken) Wait(TimeSpan, CancellationToken)

Bloquea el subproceso actual hasta que pueda entrar en SemaphoreSlim, usando un TimeSpan que especifica el tiempo de espera mientras se observa un token CancellationToken.Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan that specifies the timeout, while observing a CancellationToken.

WaitAsync() WaitAsync() WaitAsync() WaitAsync()

De forma asincrónica espera que entre el SemaphoreSlim.Asynchronously waits to enter the SemaphoreSlim.

WaitAsync(CancellationToken) WaitAsync(CancellationToken) WaitAsync(CancellationToken) WaitAsync(CancellationToken)

De forma asincrónica espera que entre el SemaphoreSlim, mientras observa CancellationToken.Asynchronously waits to enter the SemaphoreSlim, while observing a CancellationToken.

WaitAsync(Int32) WaitAsync(Int32) WaitAsync(Int32) WaitAsync(Int32)

De forma asincrónica espera que entre el SemaphoreSlim, utilizando un entero de 32 bits para medir el intervalo de tiempo.Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval.

WaitAsync(Int32, CancellationToken) WaitAsync(Int32, CancellationToken) WaitAsync(Int32, CancellationToken) WaitAsync(Int32, CancellationToken)

De forma asincrónica espera que entre el SemaphoreSlim, utilizando un entero de 32 bits para medir el intervalo de tiempo, mientras observa CancellationToken.Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval, while observing a CancellationToken.

WaitAsync(TimeSpan) WaitAsync(TimeSpan) WaitAsync(TimeSpan) WaitAsync(TimeSpan)

De forma asincrónica espera que entre el SemaphoreSlim, mediante TimeSpan para medir el intervalo de tiempo.Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval.

WaitAsync(TimeSpan, CancellationToken) WaitAsync(TimeSpan, CancellationToken) WaitAsync(TimeSpan, CancellationToken) WaitAsync(TimeSpan, CancellationToken)

De forma asincrónica espera que entre el SemaphoreSlim, mediante TimeSpan para medir el intervalo de tiempo, mientras observa CancellationToken.Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval, while observing a CancellationToken.

Se aplica a

Seguridad para subprocesos

Todos los miembros públicos y protegidos SemaphoreSlim de son seguros para subprocesos y se pueden usar simultáneamente desde varios subprocesos, con Dispose()la excepción de, que deben usarse solo cuando se SemaphoreSlim hayan completado todas las demás operaciones en.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.

Consulte también: