SemaphoreSlim Classe

Definizione

Rappresenta un'alternativa semplificata a Semaphore che limita il numero di thread che possono accedere simultaneamente a una risorsa o a un pool di risorse.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
Ereditarietà
SemaphoreSlim
Attributi
Implementazioni

Esempi

Nell'esempio seguente viene creato un semaforo con un numero massimo di tre thread e un conteggio iniziale pari a zero thread.The following example creates a semaphore with a maximum count of three threads and an initial count of zero threads. Nell'esempio vengono avviate cinque attività, tutte bloccate in attesa del semaforo.The example starts five tasks, all of which block waiting for the semaphore. Il thread principale chiama l' Release(Int32) overload per aumentare il numero di semafori al massimo, che consente a tre attività di accedere al semaforo.The main thread calls the Release(Int32) overload to increase the semaphore count to its maximum, which allows three tasks to enter the semaphore. Ogni volta che viene rilasciato il semaforo, viene visualizzato il numero di semafori precedente.Each time the semaphore is released, the previous semaphore count is displayed. I messaggi della console tengono traccia dell'uso del semaforo.Console messages track semaphore use. L'intervallo di lavoro simulato viene leggermente aumentato per ogni thread per semplificare la lettura dell'output.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.

Commenti

I semafori sono di due tipi: i semafori locali e i semafori di sistema denominati.Semaphores are of two types: local semaphores and named system semaphores. Il primo è locale per un'app.The former is local to an app. Quest'ultimo è visibile in tutto il sistema operativo ed è adatto per la sincronizzazione tra processi.The latter is visible throughout the operating system and is suitable for inter-process synchronization. È un'alternativa semplice alla classe che Semaphore non usa i semafori del kernel di Windows. SemaphoreSlimThe SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores. A differenza della Semaphore classe, la SemaphoreSlim classe non supporta i semafori di sistema denominati.Unlike the Semaphore class, the SemaphoreSlim class doesn't support named system semaphores. È possibile usarlo solo come semaforo locale.You can use it as a local semaphore only. La SemaphoreSlim classe è il semaforo consigliato per la sincronizzazione all'interno di una singola app.The SemaphoreSlim class is the recommended semaphore for synchronization within a single app.

Un semaforo leggero controlla l'accesso a un pool di risorse locale per l'applicazione.A lightweight semaphore controls access to a pool of resources that is local to your application. Quando si crea un'istanza di un semaforo, è possibile specificare il numero massimo di thread che possono accedere contemporaneamente al semaforo.When you instantiate a semaphore, you can specify the maximum number of threads that can enter the semaphore concurrently. Viene anche specificato il numero iniziale di thread che possono accedere contemporaneamente al semaforo.You also specify the initial number of threads that can enter the semaphore concurrently. Definisce il conteggio del semaforo.This defines the semaphore's count.

Il conteggio viene decrementato ogni volta che un thread entra nel semaforo e viene incrementato ogni volta che un thread rilascia il semaforo.The count is decremented each time a thread enters the semaphore, and incremented each time a thread releases the semaphore. Per accedere al semaforo, un thread chiama uno degli Wait overload o. WaitAsyncTo enter the semaphore, a thread calls one of the Wait or WaitAsync overloads. Per rilasciare il semaforo, viene chiamato uno degli Release overload.To release the semaphore, it calls one of the Release overloads. Quando il conteggio raggiunge lo zero, le chiamate successive a uno Wait dei metodi si bloccano fino a quando altri thread rilasciano il semaforo.When the count reaches zero, subsequent calls to one of the Wait methods block until other threads release the semaphore. Se più thread sono bloccati, non esiste alcun ordine garantito, ad esempio FIFO o LIFO, che controlla quando i thread entrano nel semaforo.If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

La struttura di base per il codice che usa un semaforo per proteggere le risorse è: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()  
  

Quando tutti i thread hanno rilasciato il semaforo, il conteggio corrisponde al valore massimo specificato al momento della creazione del semaforo.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created. Il numero del semaforo è disponibile dalla CurrentCount proprietà.The semaphore's count is available from the CurrentCount property.

Importante

La SemaphoreSlim classe non impone l'identità dei thread o delle attività per Waitle WaitAsyncchiamate ai Release metodi, e.The SemaphoreSlim class doesn't enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods. Se, inoltre, viene SemaphoreSlim(Int32) utilizzato il costruttore per creare un'istanza SemaphoreSlim dell'oggetto, CurrentCount la proprietà può aumentare oltre il valore impostato dal costruttore.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. È responsabilità del programmatore garantire che le chiamate ai Wait metodi o WaitAsync siano abbinate in modo appropriato alle chiamate ai Release metodi.It is the programmer's responsibility to ensure that calls to Wait or WaitAsync methods are appropriately paired with calls to Release methods.

Costruttori

SemaphoreSlim(Int32)

Inizializza una nuova istanza della classe SemaphoreSlim specificando il numero iniziale di richieste che possono essere concesse contemporaneamente.Initializes a new instance of the SemaphoreSlim class, specifying the initial number of requests that can be granted concurrently.

SemaphoreSlim(Int32, Int32)

Inizializza una nuova istanza della classe SemaphoreSlim specificando il numero iniziale e massimo di richieste che possono essere concesse contemporaneamente.Initializes a new instance of the SemaphoreSlim class, specifying the initial and maximum number of requests that can be granted concurrently.

Proprietà

AvailableWaitHandle

Restituisce un oggetto WaitHandle che può essere utilizzato per attendere il semaforo.Returns a WaitHandle that can be used to wait on the semaphore.

CurrentCount

Ottiene il numero di thread rimanenti che possono accedere all'oggetto SemaphoreSlim.Gets the number of remaining threads that can enter the SemaphoreSlim object.

Metodi

Dispose()

Rilascia tutte le risorse usate dall'istanza corrente della classe SemaphoreSlim.Releases all resources used by the current instance of the SemaphoreSlim class.

Dispose(Boolean)

Rilascia le risorse non gestite usate dall'oggetto SemaphoreSlim e, facoltativamente, le risorse gestite.Releases the unmanaged resources used by the SemaphoreSlim, and optionally releases the managed resources.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.Determines whether the specified object is equal to the current object.

(Ereditato da Object)
GetHashCode()

Funge da funzione hash predefinita.Serves as the default hash function.

(Ereditato da Object)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.Gets the Type of the current instance.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.Creates a shallow copy of the current Object.

(Ereditato da Object)
Release()

Rilascia l'oggetto SemaphoreSlim una volta.Releases the SemaphoreSlim object once.

Release(Int32)

Rilascia l'oggetto SemaphoreSlim un numero di volte specificato.Releases the SemaphoreSlim object a specified number of times.

ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.Returns a string that represents the current object.

(Ereditato da Object)
Wait()

Blocca il thread corrente finché non è in grado di accedere all'oggetto SemaphoreSlim.Blocks the current thread until it can enter the SemaphoreSlim.

Wait(CancellationToken)

Blocca il thread corrente finché quest'ultimo non è in grado di accedere all'oggetto SemaphoreSlim al contempo osservando un oggetto CancellationToken.Blocks the current thread until it can enter the SemaphoreSlim, while observing a CancellationToken.

Wait(Int32)

Blocca il thread corrente finché non è in grado di accedere all'oggetto SemaphoreSlim, utilizzando un intero con segno a 32 bit che specifica il timeout.Blocks the current thread until it can enter the SemaphoreSlim, using a 32-bit signed integer that specifies the timeout.

Wait(Int32, CancellationToken)

Blocca il thread corrente finché non è in grado di accedere all'oggetto SemaphoreSlim, utilizzando un intero con segno a 32 bit che specifica il timeout mentre al contempo osservando un oggetto 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)

Blocca il thread corrente finché quest'ultimo non può accedere all'oggetto SemaphoreSlim, utilizzando un oggetto TimeSpan per specificare il timeout.Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan to specify the timeout.

Wait(TimeSpan, CancellationToken)

Blocca il thread corrente finché non è in grado di accedere all'oggetto SemaphoreSlim, utilizzando un oggetto TimeSpan che specifica il timeout e al contempo osservando un oggetto CancellationToken.Blocks the current thread until it can enter the SemaphoreSlim, using a TimeSpan that specifies the timeout, while observing a CancellationToken.

WaitAsync()

In modo asincrono attende di immettere SemaphoreSlim.Asynchronously waits to enter the SemaphoreSlim.

WaitAsync(CancellationToken)

In modo asincrono attende di immettere SemaphoreSlim, mentre osserva CancellationToken.Asynchronously waits to enter the SemaphoreSlim, while observing a CancellationToken.

WaitAsync(Int32)

In modo asincrono attende di immettere SemaphoreSlim, utilizzando un Integer con segno a 32 bit per misurare l'intervallo di tempo.Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval.

WaitAsync(Int32, CancellationToken)

In modo asincrono attende di immettere SemaphoreSlim, utilizzando un Integer con segno a 32 bit per misurare l'intervallo di tempo, mentre osserva CancellationToken.Asynchronously waits to enter the SemaphoreSlim, using a 32-bit signed integer to measure the time interval, while observing a CancellationToken.

WaitAsync(TimeSpan)

In modo asincrono attende di immettere SemaphoreSlim, utilizzando TimeSpan per misurare l'intervallo di tempo.Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval.

WaitAsync(TimeSpan, CancellationToken)

In modo asincrono attende di immettere SemaphoreSlim, utilizzando TimeSpan per misurare l'intervallo di tempo, mentre osserva CancellationToken.Asynchronously waits to enter the SemaphoreSlim, using a TimeSpan to measure the time interval, while observing a CancellationToken.

Si applica a

Thread safety

Tutti i membri pubblici e protetti SemaphoreSlim di sono thread-safe e possono essere usati contemporaneamente da più thread, ad eccezione di Dispose(), che deve essere usato solo quando tutte le altre operazioni nell'oggetto SemaphoreSlim sono state completate.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.

Vedi anche