SemaphoreSlim Classe

Définition

Représente une alternative légère à Semaphore qui limite le nombre de threads pouvant accéder simultanément à une ressource ou à un pool de ressources.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
public class SemaphoreSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class SemaphoreSlim : IDisposable
type SemaphoreSlim = class
    interface IDisposable
Public Class SemaphoreSlim
Implements IDisposable
Héritage
SemaphoreSlim
Attributs
Implémente

Exemples

L’exemple suivant crée un sémaphore avec un nombre maximal de trois threads et un nombre initial de threads zéro.The following example creates a semaphore with a maximum count of three threads and an initial count of zero threads. L’exemple démarre cinq tâches, qui attendent toutes le sémaphore.The example starts five tasks, all of which block waiting for the semaphore. Le thread principal appelle la surcharge Release(Int32) pour augmenter le nombre de sémaphores à son maximum, ce qui permet à trois tâches d’entrer dans le sémaphore.The main thread calls the Release(Int32) overload to increase the semaphore count to its maximum, which allows three tasks to enter the semaphore. Chaque fois que le sémaphore est libéré, le nombre de sémaphores précédent est affiché.Each time the semaphore is released, the previous semaphore count is displayed. Les messages de la console suivent l’utilisation du sémaphore.Console messages track semaphore use. L’intervalle de travail simulé est légèrement augmenté pour chaque thread pour faciliter la lecture de la sortie.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.

Remarques

Les sémaphores sont de deux types : les sémaphores locaux et les sémaphores système nommés.Semaphores are of two types: local semaphores and named system semaphores. La première est locale à une application.The former is local to an app. Ce dernier est visible dans tout le système d’exploitation et convient à la synchronisation inter-processus.The latter is visible throughout the operating system and is suitable for inter-process synchronization. Le SemaphoreSlim est une alternative légère à la classe Semaphore qui n’utilise pas les sémaphores de noyau Windows.The SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores. Contrairement à la classe Semaphore, la classe SemaphoreSlim ne prend pas en charge les sémaphores système nommés.Unlike the Semaphore class, the SemaphoreSlim class doesn't support named system semaphores. Vous pouvez l’utiliser en tant que sémaphore local uniquement.You can use it as a local semaphore only. La classe SemaphoreSlim est le sémaphore recommandé pour la synchronisation au sein d’une application unique.The SemaphoreSlim class is the recommended semaphore for synchronization within a single app.

Un sémaphore léger contrôle l’accès à un pool de ressources local pour votre application.A lightweight semaphore controls access to a pool of resources that is local to your application. Lorsque vous instanciez un sémaphore, vous pouvez spécifier le nombre maximal de threads qui peuvent entrer le sémaphore simultanément.When you instantiate a semaphore, you can specify the maximum number of threads that can enter the semaphore concurrently. Vous spécifiez également le nombre initial de threads qui peuvent entrer le sémaphore simultanément.You also specify the initial number of threads that can enter the semaphore concurrently. Cela définit le nombre du sémaphore.This defines the semaphore's count.

Le nombre est décrémenté chaque fois qu’un thread entre dans le sémaphore et est incrémenté chaque fois qu’un thread libère le sémaphore.The count is decremented each time a thread enters the semaphore, and incremented each time a thread releases the semaphore. Pour entrer dans le sémaphore, un thread appelle l’une des Wait ou WaitAsync surcharges.To enter the semaphore, a thread calls one of the Wait or WaitAsync overloads. Pour libérer le sémaphore, il appelle l’une des surcharges de Release.To release the semaphore, it calls one of the Release overloads. Lorsque le nombre atteint zéro, les appels suivants à l’une des méthodes Wait sont bloqués jusqu’à ce que les autres threads libèrent le sémaphore.When the count reaches zero, subsequent calls to one of the Wait methods block until other threads release the semaphore. Si plusieurs threads sont bloqués, aucun ordre n’est garanti, tel que FIFO ou LIFO, qui contrôle le moment où les threads entrent dans le sémaphore.If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

La structure de base du code qui utilise un sémaphore pour protéger les ressources est la suivante :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()  
  

Lorsque tous les threads ont libéré le sémaphore, le nombre est à la valeur maximale spécifiée lors de la création du sémaphore.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created. Le nombre du sémaphore est disponible à partir de la propriété CurrentCount.The semaphore's count is available from the CurrentCount property.

Important

La classe SemaphoreSlim n’applique pas l’identité de thread ou de tâche sur les appels aux méthodes Wait, WaitAsyncet Release.The SemaphoreSlim class doesn't enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods. En outre, si le constructeur SemaphoreSlim(Int32) est utilisé pour instancier l’objet SemaphoreSlim, la propriété CurrentCount peut augmenter au-delà de la valeur définie par le constructeur.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. Il incombe au programmeur de s’assurer que les appels aux méthodes Wait ou WaitAsync sont associés de manière appropriée aux appels à des méthodes de Release.It is the programmer's responsibility to ensure that calls to Wait or WaitAsync methods are appropriately paired with calls to Release methods.

Constructeurs

SemaphoreSlim(Int32)

Initialise une nouvelle instance de la classe SemaphoreSlim, en spécifiant le nombre initial de demandes qui peuvent être accordées simultanément.Initializes a new instance of the SemaphoreSlim class, specifying the initial number of requests that can be granted concurrently.

SemaphoreSlim(Int32, Int32)

Initialise une nouvelle instance de la classe SemaphoreSlim, en spécifiant le nombre initial et le nombre maximal de demandes qui peuvent être accordées simultanément.Initializes a new instance of the SemaphoreSlim class, specifying the initial and maximum number of requests that can be granted concurrently.

Propriétés

AvailableWaitHandle

Retourne un WaitHandle qui peut être utilisé pour attendre sur un sémaphore.Returns a WaitHandle that can be used to wait on the semaphore.

CurrentCount

Obtient le nombre de threads restants qui peuvent accéder à l'objet SemaphoreSlim.Gets the number of remaining threads that can enter the SemaphoreSlim object.

Méthodes

Dispose()

Libère toutes les ressources utilisées par l'instance actuelle de la classe SemaphoreSlim.Releases all resources used by the current instance of the SemaphoreSlim class.

Dispose(Boolean)

Libère les ressources non managées utilisées par le SemaphoreSlim, et libère éventuellement les ressources managées.Releases the unmanaged resources used by the SemaphoreSlim, and optionally releases the managed resources.

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.Determines whether the specified object is equal to the current object.

(Hérité de Object)
GetHashCode()

Sert de fonction de hachage par défaut.Serves as the default hash function.

(Hérité de Object)
GetType()

Obtient le Type de l'instance actuelle.Gets the Type of the current instance.

(Hérité de Object)
MemberwiseClone()

Crée une copie superficielle du Object actuel.Creates a shallow copy of the current Object.

(Hérité de Object)
Release()

Libère l’objet SemaphoreSlim une seule fois.Releases the SemaphoreSlim object once.

Release(Int32)

Libère l’objet SemaphoreSlim un nombre de fois déterminé.Releases the SemaphoreSlim object a specified number of times.

ToString()

Retourne une chaîne qui représente l'objet actif.Returns a string that represents the current object.

(Hérité de Object)
Wait()

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim.Blocks the current thread until it can enter the SemaphoreSlim.

Wait(CancellationToken)

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim, tout en observant un CancellationToken.Blocks the current thread until it can enter the SemaphoreSlim, while observing a CancellationToken.

Wait(Int32)

Bloque le thread actuel jusqu'à ce qu'il puisse entrer dans SemaphoreSlim, à l'aide d'un entier signé 32 bits qui spécifie le délai d'attente.Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout.

Wait(Int32, CancellationToken)

Bloque le thread actuel jusqu'à ce qu'il puisse entrer dans SemaphoreSlim, à l'aide d'un entier signé 32 bits qui spécifie le délai d'attente, tout en observant un 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)

Bloque le thread actuel jusqu'à ce qu'il puisse entrer dans SemaphoreSlim, à l'aide d'un TimeSpan pour spécifier le délai d'attente.Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan to specify the timeout.

Wait(TimeSpan, CancellationToken)

Bloque le thread actuel jusqu'à ce qu'il puisse entrer dans SemaphoreSlim, à l'aide d'un TimeSpan qui spécifie le délai d'attente, tout en observant un CancellationToken.Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan that specifies the timeout, while observing a CancellationToken.

WaitAsync()

Attend de façon asynchrone avant d'accéder à SemaphoreSlim.Asynchronously waits to enter the SemaphoreSlim.

WaitAsync(CancellationToken)

Attend de façon asynchrone d'accéder à SemaphoreSlim, tout en observant un CancellationToken.Asynchronously waits to enter the SemaphoreSlim, while observing a CancellationToken.

WaitAsync(Int32)

Attend de façon asynchrone avant d'entrer SemaphoreSlim, en utilisant un entier signé 32 bits pour mesurer l'intervalle de temps.Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval.

WaitAsync(Int32, CancellationToken)

Attend de façon asynchrone avant d'entrer SemaphoreSlim, en utilisant un entier signé 32 bits pour mesurer l'intervalle de temps, tout en observant un CancellationToken.Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval, while observing a CancellationToken.

WaitAsync(TimeSpan)

Attend de façon asynchrone avant d'entrer SemaphoreSlim, en utilisant TimeSpan pour mesurer l'intervalle de temps.Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval.

WaitAsync(TimeSpan, CancellationToken)

Attend de façon asynchrone avant d'entrer SemaphoreSlim, en utilisant TimeSpan pour mesurer l'intervalle de temps, tout en observant un CancellationToken.Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval, while observing a CancellationToken.

S’applique à

Cohérence de thread

Tous les membres publics et protégés de SemaphoreSlim sont thread-safe et peuvent être utilisés simultanément à partir de plusieurs threads, à l’exception de Dispose(), qui doit être utilisé uniquement lorsque toutes les autres opérations sur le SemaphoreSlim sont terminées.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.

Voir aussi