Partager via


SemaphoreSlim Classe

Définition

Représente une alternative légère à Semaphore celle qui limite le nombre de threads pouvant accéder simultanément à une ressource ou à un pool de ressources.

public ref class SemaphoreSlim : IDisposable
public class SemaphoreSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class SemaphoreSlim : IDisposable
type SemaphoreSlim = class
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
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. L’exemple démarre cinq tâches, qui bloquent l’attente du sémaphore. Le thread principal appelle la Release(Int32) surcharge pour augmenter le nombre de sémaphores à son maximum, ce qui permet à trois tâches d’entrer dans le sémaphore. Chaque fois que le sémaphore est libéré, le nombre de sémaphores précédents s’affiche. Les messages de console suivent l’utilisation du sémaphore. L’intervalle de travail simulé est légèrement augmenté pour chaque thread afin de faciliter la lecture de la sortie.

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);
                
                int semaphoreCount;
                semaphore.Wait();
                try
                {
                    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);
                }
                finally {
                    semaphoreCount = semaphore.Release();
                }
                Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.",
                                  Task.CurrentId, semaphoreCount);
            });
        }

        // 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. Les sémaphores locaux sont locaux à une application, les sémaphores système sont visibles dans tout le système d’exploitation et conviennent à la synchronisation entre processus. Il SemaphoreSlim s’agit d’une alternative légère à la Semaphore classe qui n’utilise pas les sémaphores du noyau Windows. Contrairement à la Semaphore classe, la SemaphoreSlim classe ne prend pas en charge les sémaphores système nommés. Vous pouvez l’utiliser en tant que sémaphore local uniquement. La SemaphoreSlim classe est le sémaphore recommandé pour la synchronisation au sein d’une seule application.

Un sémaphore léger contrôle l’accès à un pool de ressources local pour votre application. Lorsque vous instanciez un sémaphore, vous pouvez spécifier le nombre maximal de threads pouvant entrer simultanément le sémaphore. Vous spécifiez également le nombre initial de threads qui peuvent entrer simultanément le sémaphore. Cela définit le nombre de sémaphores.

Le nombre est décrémenté chaque fois qu’un thread entre dans le sémaphore et incrémenté chaque fois qu’un thread libère le sémaphore. Pour entrer le sémaphore, un thread appelle l’une des surcharges ou WaitAsync les Wait surcharges. Pour libérer le sémaphore, il appelle l’une des Release surcharges. Lorsque le nombre atteint zéro, les appels suivants à l’une des Wait méthodes bloquent jusqu’à ce que d’autres threads libèrent le sémaphore. Si plusieurs threads sont bloqués, il n’existe aucun ordre garanti, tel que FIFO ou LIFO, qui contrôle lorsque les threads entrent dans le sémaphore.

La structure de base du code qui utilise un sémaphore pour protéger les ressources est la suivante :

' 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. Le nombre de sémaphores est disponible à partir de la CurrentCount propriété.

Important

La SemaphoreSlim classe n’applique pas l’identité de thread ou de tâche sur les appels aux méthodes et Release aux WaitappelsWaitAsync. En outre, si le SemaphoreSlim(Int32) constructeur est utilisé pour instancier l’objet SemaphoreSlim , la CurrentCount propriété peut augmenter au-delà de la valeur définie par le constructeur. Il incombe au programmeur de s’assurer que les appels à des méthodes ou WaitAsync les Wait appels sont correctement associés à des appels à Release des méthodes.

Constructeurs

Nom Description
SemaphoreSlim(Int32, Int32)

Initialise une nouvelle instance de la SemaphoreSlim classe, en spécifiant le nombre initial et maximal de requêtes qui peuvent être accordées simultanément.

SemaphoreSlim(Int32)

Initialise une nouvelle instance de la SemaphoreSlim classe, en spécifiant le nombre initial de requêtes qui peuvent être accordées simultanément.

Propriétés

Nom Description
AvailableWaitHandle

Retourne un WaitHandle qui peut être utilisé pour attendre sur le sémaphore.

CurrentCount

Obtient le nombre de threads restants qui peuvent entrer l’objet SemaphoreSlim .

Méthodes

Nom Description
Dispose()

Libère toutes les ressources utilisées par l’instance actuelle de la SemaphoreSlim classe.

Dispose(Boolean)

Libère les ressources non managées utilisées par le SemaphoreSlim, et libère éventuellement les ressources managées.

Equals(Object)

Détermine si l’objet spécifié est égal à l’objet actuel.

(Hérité de Object)
GetHashCode()

Sert de fonction de hachage par défaut.

(Hérité de Object)
GetType()

Obtient la Type de l’instance actuelle.

(Hérité de Object)
MemberwiseClone()

Crée une copie superficielle du Objectactuel.

(Hérité de Object)
Release()

Libère l’objet SemaphoreSlim une seule fois.

Release(Int32)

Libère l’objet SemaphoreSlim un nombre spécifié de fois.

ToString()

Retourne une chaîne qui représente l’objet actuel.

(Hérité de Object)
Wait()

Bloque le thread actuel jusqu’à ce qu’il puisse entrer le SemaphoreSlim.

Wait(CancellationToken)

Bloque le thread actuel jusqu’à ce qu’il puisse entrer dans le SemaphoreSlim, tout en observant un CancellationToken.

Wait(Int32, CancellationToken)

Bloque le thread actuel jusqu’à ce qu’il puisse entrer , à l’aide SemaphoreSlimd’un entier signé 32 bits qui spécifie le délai d’expiration, lors de l’observation d’un CancellationToken.

Wait(Int32)

Bloque le thread actuel jusqu’à ce qu’il puisse entrer , à l’aide SemaphoreSlimd’un entier signé 32 bits qui spécifie le délai d’expiration.

Wait(TimeSpan, CancellationToken)

Bloque le thread actuel jusqu’à ce qu’il puisse entrer le SemaphoreSlim, en utilisant un TimeSpan qui spécifie le délai d’attente, tout en observant un CancellationToken.

Wait(TimeSpan)

Bloque le thread actuel jusqu’à ce qu’il puisse entrer , à l’aide SemaphoreSlimd’un TimeSpan pour spécifier le délai d’expiration.

WaitAsync()

Attend de façon asynchrone d’entrer le SemaphoreSlim.

WaitAsync(CancellationToken)

Attend de façon asynchrone d’entrer le , lors de l’observation SemaphoreSlimd’un CancellationToken.

WaitAsync(Int32, CancellationToken)

Attend de façon asynchrone d’entrer le , à l’aide SemaphoreSlimd’un entier signé 32 bits pour mesurer l’intervalle de temps, lors de l’observation d’un CancellationToken.

WaitAsync(Int32)

Attend de façon asynchrone d’entrer l’entier SemaphoreSlimsigné 32 bits pour mesurer l’intervalle de temps.

WaitAsync(TimeSpan, CancellationToken)

Attend de façon asynchrone d’entrer le SemaphoreSlim, en utilisant un TimeSpan pour mesurer l’intervalle de temps, lors de l’observation d’un CancellationToken.

WaitAsync(TimeSpan)

Attend de façon asynchrone d’entrer le SemaphoreSlim, à l’aide d’une TimeSpan mesure de l’intervalle de temps.

S’applique à

Cohérence de thread

Tous les membres publics et protégés sont SemaphoreSlim thread-safe et peuvent être utilisés simultanément à partir de plusieurs threads, à l’exception de Dispose(), qui ne doivent être utilisés que lorsque toutes les autres opérations sur le site SemaphoreSlim sont terminées.

Voir aussi