Panoramica delle primitive di sincronizzazioneOverview of synchronization primitives

.NET offre una gamma di tipi che è possibile usare per sincronizzare l'accesso a una risorsa condivisa o coordinare l'interazione tra thread..NET provides a range of types that you can use to synchronize access to a shared resource or coordinate thread interaction.

Importante

Usare la stessa istanza di primitiva di sincronizzazione per proteggere l'accesso a una risorsa condivisa.Use the same synchronization primitive instance to protect access of a shared resource. Se si usano istanze di primitive di sincronizzazione diverse per proteggere la stessa risorsa, sarà possibile aggirare la protezione fornita da una primitiva di sincronizzazione.If you use different synchronization primitive instances to protect the same resource, you'll circumvent the protection provided by a synchronization primitive.

Classe WaitHandle e tipi di sincronizzazione leggeriWaitHandle class and lightweight synchronization types

Più primitive di sincronizzazione .NET derivano dalla classe System.Threading.WaitHandle, che incapsula un handle di sincronizzazione del sistema operativo nativo e usa un meccanismo di segnalazione per l'interazione tra thread.Multiple .NET synchronization primitives derive from the System.Threading.WaitHandle class, which encapsulates a native operating system synchronization handle and uses a signaling mechanism for thread interaction. Tali classi includono:Those classes include:

  • System.Threading.Mutex, che concede l'accesso esclusivo a una risorsa condivisa.System.Threading.Mutex, which grants exclusive access to a shared resource. Lo stato di un mutex viene segnalato se nessun thread lo possiede.The state of a mutex is signaled if no thread owns it.
  • System.Threading.Semaphore, che limita il numero di thread che possono accedere simultaneamente a una risorsa condivisa o a un pool di risorse.System.Threading.Semaphore, which limits the number of threads that can access a shared resource or a pool of resources concurrently. Lo stato di un semaforo denominato è impostato come segnalato quando il relativo conteggio è maggiore di zero e come non segnalato quando il relativo conteggio è zero.The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero.
  • System.Threading.EventWaitHandle, che rappresenta un evento di sincronizzazione di thread e può trovarsi in uno stato segnalato o non segnalato.System.Threading.EventWaitHandle, which represents a thread synchronization event and can be either in a signaled or unsignaled state.
  • System.Threading.AutoResetEvent, che deriva da EventWaitHandle e, quando segnalata si reimposta automaticamente in uno stato non segnalato dopo il rilascio di un singolo thread in attesa.System.Threading.AutoResetEvent, which derives from EventWaitHandle and, when signaled, resets automatically to an unsignaled state after releasing a single waiting thread.
  • System.Threading.ManualResetEvent, che deriva da EventWaitHandle e, quando segnalata, rimane in uno stato segnalato finché non viene chiamato il metodo Reset.System.Threading.ManualResetEvent, which derives from EventWaitHandle and, when signaled, stays in a signaled state until the Reset method is called.

In .NET Framework, poiché WaitHandle deriva da System.MarshalByRefObject, questi tipi possono essere usati per sincronizzare le attività dei thread tra limiti dei domini delle applicazioni.In the .NET Framework, because WaitHandle derives from System.MarshalByRefObject, these types can be used to synchronize the activities of threads across application domain boundaries.

In .NET Framework e .NET Core, alcuni di questi tipi possono rappresentare handle di sincronizzazione di sistema denominati, che sono visibili in tutto il sistema operativo e possono essere usati per la sincronizzazione interprocesso:In the .NET Framework and .NET Core, some of these types can represent named system synchronization handles, which are visible throughout the operating system and can be used for the inter-process synchronization:

  • Mutex (.NET Framework e .NET Core).Mutex (.NET Framework and .NET Core),
  • Semaphore (.NET Framework e .NET Core in Windows).Semaphore (.NET Framework and .NET Core on Windows),
  • EventWaitHandle (.NET Framework e .NET Core in Windows).EventWaitHandle (.NET Framework and .NET Core on Windows).

Per altre informazioni, vedere le informazioni di riferimento sull'API WaitHandle.For more information, see the WaitHandle API reference.

I tipi di sincronizzazione leggeri non si basano su handle del sistema operativo sottostanti e in genere offrono prestazioni migliori.Lightweight synchronization types don't rely on underlying operating system handles and typically provide better performance. Tuttavia, non possono essere usati per la sincronizzazione interprocesso.However, they cannot be used for the inter-process synchronization. Usare tali tipi per la sincronizzazione dei thread all'interno di un'applicazione.Use those types for thread synchronization within one application.

Alcuni di questi tipi rappresentano alternative ai tipi derivati da WaitHandle.Some of those types are alternatives to the types derived from WaitHandle. Ad esempio, SemaphoreSlim è un'alternativa leggera a Semaphore.For example, SemaphoreSlim is a lightweight alternative to Semaphore.

Sincronizzazione dell'accesso a una risorsa condivisaSynchronization of access to a shared resource

.NET offre una gamma di primitive di sincronizzazione per controllare l'accesso a una risorsa condivisa da parte di più thread..NET provides a range of synchronization primitives to control access to a shared resource by multiple threads.

Monitor (classe)Monitor class

La classe System.Threading.Monitor concede l'accesso con esclusione reciproca a una risorsa condivisa tramite l'acquisizione o il rilascio di un blocco sull'oggetto che identifica la risorsa.The System.Threading.Monitor class grants mutually exclusive access to a shared resource by acquiring or releasing a lock on the object that identifies the resource. Mentre è attivo un blocco, il thread che contiene il blocco può ancora acquisire e rilasciare il blocco.While a lock is held, the thread that holds the lock can again acquire and release the lock. Gli altri thread non possono acquisire il blocco e il metodo Monitor.Enter attende il rilascio del blocco.Any other thread is blocked from acquiring the lock and the Monitor.Enter method waits until the lock is released. Il metodo Enter acquisisce un blocco rilasciato.The Enter method acquires a released lock. È anche possibile usare il metodo Monitor.TryEnter per specificare l'intervallo di tempo durante il quale un thread cerca di acquisire un blocco.You can also use the Monitor.TryEnter method to specify the amount of time during which a thread attempts to acquire a lock. Poiché la classe Monitor presenta affinità di thread, il thread che ha acquisito un blocco deve rilasciare il blocco chiamando il metodo Monitor.Exit.Because the Monitor class has thread affinity, the thread that acquired a lock must release the lock by calling the Monitor.Exit method.

È possibile coordinare l'interazione tra i thread che acquisiscono un blocco sullo stesso oggetto usando i metodi Monitor.Wait, Monitor.Pulse e Monitor.PulseAll.You can coordinate the interaction of threads that acquire a lock on the same object by using the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll methods.

Per altre informazioni, vedere le informazioni di riferimento sull'API Monitor.For more information, see the Monitor API reference.

Nota

Usare l'istruzione lock in C# e l'istruzione SyncLock in Visual Basic per sincronizzare l'accesso a una risorsa condivisa invece di usare direttamente la classe Monitor.Use the lock statement in C# and the SyncLock statement in Visual Basic to synchronize access to a shared resource instead of using the Monitor class directly. Queste istruzioni vengono implementate usando i metodi Enter e Exit e un blocco try…finally per garantire che il blocco acquisito venga sempre rilasciato.Those statements are implemented by using the Enter and Exit methods and a try…finally block to ensure that the acquired lock is always released.

Mutex (classe)Mutex class

La classe System.Threading.Mutex, analogamente a Monitor, concede l'accesso esclusivo a una risorsa condivisa.The System.Threading.Mutex class, like Monitor, grants exclusive access to a shared resource. Usare uno degli overload del metodo Mutex.WaitOne per richiedere la proprietà di un mutex.Use one of the Mutex.WaitOne method overloads to request the ownership of a mutex. Analogamente a Monitor, Mutex presenta affinità di thread e il thread che ha acquisito un mutex deve rilasciarlo chiamando il metodo Mutex.ReleaseMutex.Like Monitor, Mutex has thread affinity and the thread that acquired a mutex must release it by calling the Mutex.ReleaseMutex method.

A differenza di Monitor, la classe Mutex può essere usata per la sincronizzazione interprocesso.Unlike Monitor, the Mutex class can be used for inter-process synchronization. A tale scopo, usare un mutex denominato, visibile in tutto il sistema operativo.To do that, use a named mutex, which is visible throughout the operating system. Per creare un'istanza di mutex denominata, usare un costruttore di Mutex che specifica un nome.To create a named mutex instance, use a Mutex constructor that specifies a name. È anche possibile chiamare il metodo Mutex.OpenExisting per aprire un mutex di sistema denominato esistente.You also can call the Mutex.OpenExisting method to open an existing named system mutex.

Per altre informazioni, vedere l'articolo Mutex e le informazioni di riferimento sull'API Mutex.For more information, see the Mutexes article and the Mutex API reference.

Struttura SpinLockSpinLock structure

La struttura System.Threading.SpinLock, analogamente a Monitor, concede l'accesso esclusivo a una risorsa condivisa in base alla disponibilità di un blocco.The System.Threading.SpinLock structure, like Monitor, grants exclusive access to a shared resource based on the availability of a lock. Quando SpinLock cerca di acquisire un blocco che non è disponibile, rimane in attesa in un ciclo eseguendo controlli ripetuti finché il blocco non diventa disponibile.When SpinLock attempts to acquire a lock that is unavailable, it waits in a loop, repeatedly checking until the lock becomes available.

Per altre informazioni sui vantaggi e sugli svantaggi dell'uso del meccanismo di spinlock, vedere l'articolo SpinLock e le informazioni di riferimento sull'API SpinLock.For more information about the benefits and drawbacks of using spin lock, see the SpinLock article and the SpinLock API reference.

Classe ReaderWriterLockSlimReaderWriterLockSlim class

La classe System.Threading.ReaderWriterLockSlim concede l'accesso esclusivo a una risorsa condivisa per la scrittura e permette a più thread di accedere alla risorsa simultaneamente per la lettura.The System.Threading.ReaderWriterLockSlim class grants exclusive access to a shared resource for writing and allows multiple threads to access the resource simultaneously for reading. È possibile usare ReaderWriterLockSlim per sincronizzare l'accesso a una struttura dei dati condivisa che supporta operazioni di lettura thread-safe, ma richiede accesso esclusivo per eseguire le operazioni di scrittura.You might want to use ReaderWriterLockSlim to synchronize access to a shared data structure that supports thread-safe read operations, but requires exclusive access to perform write operation. Quando un thread richiede l'accesso esclusivo, ad esempio chiamando il metodo ReaderWriterLockSlim.EnterWriteLock, le richieste di lettore e scrittore successive vengono bloccate finché tutti i lettori esistenti non escono dal blocco e lo scrittore non è entrato e uscito dal blocco.When a thread requests exclusive access (for example, by calling the ReaderWriterLockSlim.EnterWriteLock method), subsequent reader and writer requests block until all existing readers have exited the lock, and the writer has entered and exited the lock.

Per altre informazioni, vedere le informazioni di riferimento sull'API ReaderWriterLockSlim.For more information, see the ReaderWriterLockSlim API reference.

Classi Semaphore e SemaphoreSlimSemaphore and SemaphoreSlim classes

Le classi System.Threading.Semaphore e System.Threading.SemaphoreSlim limitano il numero di thread che possono accedere simultaneamente a una risorsa condivisa o a un pool di risorse.The System.Threading.Semaphore and System.Threading.SemaphoreSlim classes limit the number of threads that can access a shared resource or a pool of resources concurrently. I thread aggiuntivi che richiedono la risorsa rimangono in attesa finché un thread non rilascia il semaforo.Additional threads that request the resource wait until any thread releases the semaphore. Poiché il semaforo non presenta affinità di thread, un thread può acquisire il semaforo e un altro può rilasciarlo.Because the semaphore doesn't have thread affinity, a thread can acquire the semaphore and another one can release it.

La classe SemaphoreSlim è un'alternativa leggera a Semaphore e può essere usata solo per la sincronizzazione all'interno di un unico processo.SemaphoreSlim is a lightweight alternative to Semaphore and can be used only for synchronization within a single process boundary.

In Windows è possibile usare Semaphore per la sincronizzazione interprocesso.On Windows, you can use Semaphore for the inter-process synchronization. A tale scopo, creare un'istanza di Semaphore che rappresenta un semaforo di sistema denominato usando uno dei costruttori di Semaphore che specifica un nome o il metodo Semaphore.OpenExisting.To do that, create a Semaphore instance that represents a named system semaphore by using one of the Semaphore constructors that specifies a name or the Semaphore.OpenExisting method. SemaphoreSlim non supporta semafori di sistema denominati.SemaphoreSlim doesn't support named system semaphores.

Per altre informazioni, vedere l'articolo Semaphore e SemaphoreSlim e le informazioni di riferimento sull'API Semaphore o SemaphoreSlim.For more information, see the Semaphore and SemaphoreSlim article and the Semaphore or SemaphoreSlim API reference.

Interazione tra thread o segnalazioneThread interaction, or signaling

L'interazione tra thread (o segnalazione tra thread) significa che un thread deve attendere la notifica, o un segnale, da uno o più thread per procedere.Thread interaction (or thread signaling) means that a thread must wait for notification, or a signal, from one or more threads in order to proceed. Se, ad esempio, il thread A chiama il metodo Thread.Join del thread B, il thread A è bloccato fino al completamento del thread B.For example, if thread A calls the Thread.Join method of thread B, thread A is blocked until thread B completes. Le primitive di sincronizzazione descritte nella sezione precedente forniscono un meccanismo diverso per la segnalazione. Rilasciando un blocco, un thread notifica a un altro thread che quest'ultimo può procedere acquisendo il blocco.The synchronization primitives described in the preceding section provide a different mechanism for signaling: by releasing a lock, a thread notifies another thread that it can proceed by acquiring the lock.

Questa sezione descrive i costrutti di segnalazione aggiuntivi forniti da .NET.This section describes additional signaling constructs provided by .NET.

Classi EventWaitHandle, AutoResetEvent, ManualResetEvent e ManualResetEventSlimEventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim classes

La classe System.Threading.EventWaitHandle rappresenta un evento di sincronizzazione di thread.The System.Threading.EventWaitHandle class represents a thread synchronization event.

Un evento di sincronizzazione può trovarsi in uno stato segnalato o non segnalato.A synchronization event can be either in an unsignaled or signaled state. Quando lo stato di un evento è non segnalato, un thread che chiama l'overload WaitOne dell'evento rimane bloccato fino a quando un evento non viene segnalato.When the state of an event is unsignaled, a thread that calls the event's WaitOne overload is blocked until an event is signaled. Il metodo EventWaitHandle.Set imposta lo stato di un evento come segnalato.The EventWaitHandle.Set method sets the state of an event to signaled.

Il comportamento di un oggetto EventWaitHandle che è stato segnalato dipende dalla modalità di reimpostazione:The behavior of an EventWaitHandle that has been signaled depends on its reset mode:

In Windows è possibile usare EventWaitHandle per la sincronizzazione interprocesso.On Windows, you can use EventWaitHandle for the inter-process synchronization. A tale scopo, creare un'istanza di EventWaitHandle che rappresenta un evento di sincronizzazione di sistema denominato usando uno dei costruttori di EventWaitHandle che specifica un nome o il metodo EventWaitHandle.OpenExisting.To do that, create a EventWaitHandle instance that represents a named system synchronization event by using one of the EventWaitHandle constructors that specifies a name or the EventWaitHandle.OpenExisting method.

Per altre informazioni, vedere l'articolo EventWaitHandle.For more information, see the EventWaitHandle article. Per informazioni di riferimento sulle API, vedere EventWaitHandle, AutoResetEvent, ManualResetEvent e ManualResetEventSlim.For the API reference, see EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim.

Classe CountdownEventCountdownEvent class

La classe System.Threading.CountdownEvent rappresenta un evento che viene impostato quando il relativo conteggio è zero.The System.Threading.CountdownEvent class represents an event that becomes set when its count is zero. Quando CountdownEvent.CurrentCount è maggiore di zero, un thread che chiama CountdownEvent.Wait viene bloccato.While CountdownEvent.CurrentCount is greater than zero, a thread that calls CountdownEvent.Wait is blocked. Chiamare CountdownEvent.Signal per ridurre il conteggio di un evento.Call CountdownEvent.Signal to decrement an event's count.

A differenza di ManualResetEvent o ManualResetEventSlim, che è possibile usare per sbloccare più thread con un segnale da un thread, è possibile usare CountdownEvent per sbloccare uno o più thread con segnali da più thread.In contrast to ManualResetEvent or ManualResetEventSlim, which you can use to unblock multiple threads with a signal from one thread, you can use CountdownEvent to unblock one or more threads with signals from multiple threads.

Per altre informazioni, vedere l'articolo CountdownEvent e le informazioni di riferimento sull'API CountdownEvent.For more information, see the CountdownEvent article and the CountdownEvent API reference.

Classe BarrierBarrier class

La classe System.Threading.Barrier rappresenta una barriera di esecuzione di thread.The System.Threading.Barrier class represents a thread execution barrier. Un thread che chiama il metodo Barrier.SignalAndWait segnala di aver raggiunto la barriera e attende fino a quando gli altri thread partecipanti non raggiungono la barriera.A thread that calls the Barrier.SignalAndWait method signals that it reached the barrier and waits until other participant threads reach the barrier. Quando tutti i thread partecipanti raggiungono la barriera, procedono e la barriera viene reimpostata e può essere usata di nuovo.When all participant threads reach the barrier, they proceed and the barrier is reset and can be used again.

È possibile usare Barrier quando uno o più thread richiedono i risultati di altri thread prima di continuare con la fase di calcolo successiva.You might use Barrier when one or more threads require the results of other threads before proceeding to the next computation phase.

Per altre informazioni, vedere l'articolo Barrier e le informazioni di riferimento sull'API Barrier.For more information, see the Barrier article and the Barrier API reference.

Interlocked (classe)Interlocked class

La classe System.Threading.Interlocked fornisce metodi statici che eseguono operazioni atomiche semplici su una variabile.The System.Threading.Interlocked class provides static methods that perform simple atomic operations on a variable. Queste operazioni atomiche includono addizione, incremento e decremento, scambio e scambio condizionale in base a un confronto, oltre che l'operazione di lettura di un valore intero a 64 bit.Those atomic operations include addition, increment and decrement, exchange and conditional exchange that depends on a comparison, and read operation of a 64-bit integer value.

Per altre informazioni, vedere le informazioni di riferimento sull'API Interlocked.For more information, see the Interlocked API reference.

Struttura SpinWaitSpinWait structure

La struttura System.Threading.SpinWait fornisce supporto per l'attesa basata su rotazione.The System.Threading.SpinWait structure provides support for spin-based waiting. È possibile usare questa struttura quando un thread deve attendere che un evento venga segnalato o una condizione soddisfatta, ma quando si prevede che il tempo di attesa effettivo sia inferiore a quello richiesto usando un handle di attesa o bloccando in altro modo il thread corrente.You might want to use it when a thread has to wait for an event to be signaled or a condition to be met, but when the actual wait time is expected to be less than the waiting time required by using a wait handle or by otherwise blocking the thread. Usando SpinWait, è possibile specificare un breve intervallo di tempo di rotazione durante l'attesa e quindi produrre un risultato (ad esempio, mediante l'attesa o la sospensione) solo se la condizione non viene soddisfatta nel tempo specificato.By using SpinWait, you can specify a short period of time to spin while waiting, and then yield (for example, by waiting or sleeping) only if the condition was not met in the specified time.

Per altre informazioni, vedere l'articolo SpinWait e le informazioni di riferimento sull'API SpinWait.For more information, see the SpinWait article and the SpinWait API reference.

Vedere ancheSee also