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.

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 surcharge pour augmenter le Release(Int32) 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 précédent de sémaphores s’affiche. Les messages console suivent l’utilisation du sémaphore. L’intervalle de travail simulé est légèrement augmenté pour chaque thread pour 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 tout au long du système d’exploitation et conviennent à la synchronisation inter-processus. Il SemaphoreSlim s’agit d’une alternative légère à la Semaphore classe qui n’utilise pas Windows sémaphores de noyau. Contrairement à la Semaphore classe, la SemaphoreSlim classe ne prend pas en charge les sémaphores système nommés. Vous pouvez l’utiliser comme sémaphore local uniquement. La SemaphoreSlim classe est la sémaphore recommandée pour la synchronisation au sein d’une seule application.

Un sémaphore léger contrôle l’accès à un pool de ressources local à votre application. Lorsque vous instanciez un sémaphore, vous pouvez spécifier le nombre maximal de threads pouvant entrer simultanément dans le sémaphore. Vous spécifiez également le nombre initial de threads pouvant 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’un des blocs de Wait méthodes 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 WaitAsyncRelease aux Waitappels. 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 à Wait ou WaitAsync méthodes sont correctement jumelés avec les appels aux Release méthodes.

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.

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.

Propriétés

AvailableWaitHandle

Retourne un WaitHandle qui peut être utilisé pour l'attente sur le sémaphore.

CurrentCount

Obtient le nombre de threads restants qui peuvent accéder à l'objet SemaphoreSlim.

Méthodes

Dispose()

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

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()

Fait office de fonction de hachage par défaut.

(Hérité de Object)
GetType()

Obtient le Type de l'instance actuelle.

(Hérité de Object)
MemberwiseClone()

Crée une copie superficielle du Object actuel.

(Hérité de Object)
Release()

Libère l’objet SemaphoreSlim une seule fois.

Release(Int32)

Libère l’objet SemaphoreSlim un nombre de fois déterminé.

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 dans SemaphoreSlim.

Wait(CancellationToken)

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim, tout en observant un CancellationToken.

Wait(Int32)

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim, à l'aide d'un entier signé 32 bits qui spécifie le délai d'attente.

Wait(Int32, CancellationToken)

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim, à l'aide d'un entier signé 32 bits qui spécifie le délai d'attente, tout en observant un CancellationToken.

Wait(TimeSpan)

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim, à l'aide d'un TimeSpan pour spécifier le délai d'attente.

Wait(TimeSpan, CancellationToken)

Bloque le thread actuel jusqu'à ce qu'il puisse accéder à SemaphoreSlim, à l'aide d'un TimeSpan qui spécifie le délai d'attente, tout en observant un CancellationToken.

WaitAsync()

De façon asynchrone attentes d'entrer SemaphoreSlim.

WaitAsync(CancellationToken)

Attend de façon asynchrone avant d'entrer SemaphoreSlim, tout en observant un CancellationToken.

WaitAsync(Int32)

Attend de façon asynchrone d'accéder à SemaphoreSlim, à l'aide d'un entier signé 32 bits pour mesurer l'intervalle de temps.

WaitAsync(Int32, CancellationToken)

Attend de façon asynchrone d'accéder à SemaphoreSlim, à l'aide d'un entier signé 32 bits pour mesurer l'intervalle de temps, tout en observant un CancellationToken.

WaitAsync(TimeSpan)

Attend de façon asynchrone d'accéder à SemaphoreSlim, à l'aide d'un TimeSpan pour mesurer l'intervalle de temps.

WaitAsync(TimeSpan, CancellationToken)

Attend de façon asynchrone d'accéder à SemaphoreSlim, à l'aide d'un TimeSpan pour mesurer l'intervalle de temps, tout en observant un CancellationToken.

S’applique à

Cohérence de thread

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

Voir aussi