Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
.NET offre diversi tipi utili nella programmazione parallela, tra cui un set di classi di raccolta simultanee, primitive di sincronizzazione leggere e tipi per l'inizializzazione differita. È possibile usare questi tipi con qualsiasi codice dell'applicazione multithreading, tra cui Task Parallel Library e PLINQ.
Classi di raccolta simultanee
Le classi di collezione nel namespace System.Collections.Concurrent forniscono operazioni di aggiunta e rimozione thread-safe che evitano blocchi laddove possibile e usano blocchi con granularità fine quando necessari. Una classe di raccolta simultanea non richiede il codice utente per accettare blocchi quando accede agli elementi. Le classi di raccolta simultanee possono migliorare significativamente le prestazioni rispetto a tipi come System.Collections.ArrayList e System.Collections.Generic.List<T> (con blocco implementato dall'utente) in scenari in cui più thread aggiungono e rimuovono elementi da una raccolta.
Nella tabella seguente sono elencate le classi di raccolta simultanee:
| TIPO | Descrizione |
|---|---|
| System.Collections.Concurrent.BlockingCollection<T> | Fornisce funzionalità di blocco e delimitazione per le raccolte thread-safe che implementano System.Collections.Concurrent.IProducerConsumerCollection<T>. I thread produttori si bloccano se non sono disponibili spazi o se la raccolta è piena. I thread dei consumer si bloccano se la raccolta è vuota. Questo tipo supporta anche l'accesso non bloccante da parte di consumatori e produttori. BlockingCollection<T> può essere usato come classe di base o come archivio di backup per fornire il blocco e il delimitazione per qualsiasi classe di raccolta che supporta IEnumerable<T>. |
| System.Collections.Concurrent.ConcurrentBag<T> | Implementazione del contenitore thread-safe che fornisce operazioni di aggiunta e recupero scalabili. |
| System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue> | Tipo di dizionario simultaneo e scalabile. |
| System.Collections.Concurrent.ConcurrentQueue<T> | Coda FIFO simultanea e scalabile. |
| System.Collections.Concurrent.ConcurrentStack<T> | Stack LIFO simultaneo e scalabile. |
Per altre informazioni, vedere raccolteThread-Safe.
Primitive di sincronizzazione
Le primitive di sincronizzazione nello System.Threading spazio dei nomi consentono una concorrenza a grana fine e prestazioni migliori evitando meccanismi di blocco onerosi trovati nel codice multithreading legacy.
Nella tabella seguente sono elencati i tipi di sincronizzazione:
| TIPO | Descrizione |
|---|---|
| System.Threading.Barrier | Consente a più thread di lavorare su un algoritmo in parallelo fornendo un punto in cui ogni attività può segnalare l'arrivo e quindi bloccare fino a quando non sono arrivate alcune o tutte le attività. Per altre informazioni, vedere Barriera. |
| System.Threading.CountdownEvent | Semplifica gli scenari di fork e join fornendo un semplice meccanismo di sincronizzazione. Per altre informazioni, vedere CountdownEvent. |
| System.Threading.ManualResetEventSlim | Primitiva di sincronizzazione simile a System.Threading.ManualResetEvent. ManualResetEventSlim è più leggero, ma può essere usato solo per la comunicazione intra-processo. |
| System.Threading.SemaphoreSlim | Primitiva di sincronizzazione che limita il numero di thread che possono accedere simultaneamente a una risorsa o a un pool di risorse. Per altre informazioni, vedere Semaforo e SemaforoSlim. |
| System.Threading.SpinLock | Primitiva del blocco di esclusione reciproca che causa il thread che sta tentando di acquisire il blocco per attendere in un ciclo, o spin, per un periodo di tempo prima di produrre il relativo quantum. Negli scenari in cui l'attesa del blocco dovrebbe essere breve, SpinLock offre prestazioni migliori rispetto ad altre forme di blocco. Per altre informazioni, vedere SpinLock. |
| System.Threading.SpinWait | Tipo piccolo e leggero che verrà ruotato per un periodo di tempo specificato e infine inserisce il thread in uno stato di attesa se viene superato il conteggio delle rotazioni. Per altre informazioni, vedere SpinWait. |
Per altre informazioni, vedere:
Procedura: Usare SpinLock per la sincronizzazione di Low-Level
Procedura: Sincronizzare le operazioni simultanee con una barriera.
Classi di inizializzazione pigra
Con l'inizializzazione pigra, la memoria per un oggetto non viene allocata fino a quando non è necessaria. L'inizializzazione differita può migliorare le prestazioni distribuendo le allocazioni degli oggetti in modo uniforme nella durata di un programma. È possibile abilitare l'inizializzazione differita per qualsiasi tipo personalizzato incapsulando il tipo Lazy<T>.
La tabella seguente elenca i tipi di inizializzazione pigra:
| TIPO | Descrizione |
|---|---|
| System.Lazy<T> | Fornisce un'inizializzazione pigra, leggera e thread-safe. |
| System.Threading.ThreadLocal<T> | Fornisce un valore inizializzato in modo pigro su base per thread, con ogni thread che richiama pigramente la funzione di inizializzazione. |
| System.Threading.LazyInitializer | Fornisce metodi statici che evitano la necessità di allocare un'istanza di inizializzazione pigra. Usano invece riferimenti per assicurarsi che le destinazioni siano state inizializzate man mano che si accede. |
Per altre informazioni, vedere Inizializzazione differita.
Aggregazione di eccezioni
Il System.AggregateException tipo può essere usato per acquisire più eccezioni generate contemporaneamente in thread separati e restituirle al thread di join come singola eccezione. I tipi System.Threading.Tasks.Task e System.Threading.Tasks.Parallel e PLINQ usano ampiamente AggregateException a questo scopo. Per altre informazioni, vedere Gestione delle eccezioni e Procedura: Gestire le eccezioni in una query PLINQ.