ThreadPool Classe
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Fornisce un pool di thread che possono essere usati per eseguire attività, pubblicare elementi di lavoro, elaborare operazioni di I/O asincrone, attendere per conto di altri thread e timer di elaborazione.
public ref class ThreadPool sealed
public ref class ThreadPool abstract sealed
public sealed class ThreadPool
public static class ThreadPool
type ThreadPool = class
Public NotInheritable Class ThreadPool
Public Class ThreadPool
- Ereditarietà
-
ThreadPool
Esempio
Nell'esempio seguente il thread dell'applicazione principale accoda un metodo denominato ThreadProc per l'esecuzione in un thread del pool di thread, sospendo per un secondo e quindi esce. Il ThreadProc metodo visualizza semplicemente un messaggio.
using System;
using System.Threading;
public class Example
{
public static void Main()
{
// Queue the task.
ThreadPool.QueueUserWorkItem(ThreadProc);
Console.WriteLine("Main thread does some work, then sleeps.");
Thread.Sleep(1000);
Console.WriteLine("Main thread exits.");
}
// This thread procedure performs the task.
static void ThreadProc(Object stateInfo)
{
// No state object was passed to QueueUserWorkItem, so stateInfo is null.
Console.WriteLine("Hello from the thread pool.");
}
}
// The example displays output like the following:
// Main thread does some work, then sleeps.
// Hello from the thread pool.
// Main thread exits.
Imports System.Threading
Public Module Example
Public Sub Main()
' Queue the work for execution.
ThreadPool.QueueUserWorkItem(AddressOf ThreadProc)
Console.WriteLine("Main thread does some work, then sleeps.")
Thread.Sleep(1000)
Console.WriteLine("Main thread exits.")
End Sub
' This thread procedure performs the task.
Sub ThreadProc(stateInfo As Object)
' No state object was passed to QueueUserWorkItem, so stateInfo is null.
Console.WriteLine("Hello from the thread pool.")
End Sub
End Module
' The example displays output like the following:
' Main thread does some work, then sleeps.
' Hello from the thread pool.
' Main thread exits.
Se si imposta come commento la chiamata al Thread.Sleep metodo , il thread principale viene chiuso prima dell'esecuzione del metodo nel thread del pool di thread. Il pool di thread usa thread in background, che non mantengono l'applicazione in esecuzione se tutti i thread in primo piano hanno terminato. Si tratta di un semplice esempio di race condition.
Commenti
Molte applicazioni creano thread che impiegano molto tempo nello stato di sospensione, in attesa che si verifichi un evento. Altri thread potrebbero entrare in uno stato di sospensione solo per essere risvegliati periodicamente per eseguire il polling di una modifica o aggiornare le informazioni sullo stato. Il pool di thread consente di usare thread in modo più efficiente fornendo all'applicazione un pool di thread di lavoro gestiti dal sistema. Di seguito sono riportati alcuni esempi di operazioni che usano thread del pool di thread:
Quando si crea un Task oggetto o Task<TResult> per eseguire alcune attività in modo asincrono, per impostazione predefinita l'attività è pianificata per l'esecuzione in un thread del pool di thread.
I timer asincroni usano il pool di thread. I thread del pool di thread eseguono callback dalla System.Threading.Timer classe e generano eventi dalla System.Timers.Timer classe .
Quando si usano handle di attesa registrati, un thread di sistema monitora lo stato degli handle di attesa. Al termine di un'operazione di attesa, un thread di lavoro dal pool di thread esegue la funzione di callback corrispondente.
Quando si chiama il QueueUserWorkItem metodo per accodare un metodo per l'esecuzione in un thread del pool di thread. A tale scopo, passare il metodo un WaitCallback delegato. Il delegato ha la firma
void WaitCallback(Object state)Sub WaitCallback(state As Object)dove
stateè un oggetto che contiene i dati da utilizzare dal delegato. I dati effettivi possono essere passati al delegato chiamando il QueueUserWorkItem(WaitCallback, Object) metodo .
Note
I thread nel pool di thread gestiti sono thread in background. Ovvero, le relative IsBackground proprietà sono true. Ciò significa che un ThreadPool thread non manterrà un'applicazione in esecuzione dopo l'uscita di tutti i thread in primo piano.
Importante
Quando il pool di thread riutilizza un thread, non cancella i dati nell'archiviazione locale del thread o nei campi contrassegnati con l'attributo ThreadStaticAttribute . Pertanto, quando un metodo esamina l'archiviazione locale del thread o i campi contrassegnati con l'attributo ThreadStaticAttribute , i valori trovati potrebbero essere lasciati da un uso precedente del thread del pool di thread.
È anche possibile accodare elementi di lavoro non correlati a un'operazione di attesa al pool di thread. Per richiedere che un elemento di lavoro venga gestito da un thread nel pool di thread, chiamare il QueueUserWorkItem metodo . Questo metodo accetta come parametro un riferimento al metodo o al delegato che verrà chiamato dal thread selezionato dal pool di thread. Non è possibile annullare un elemento di lavoro dopo che è stato accodato.
I timer della coda timer e le operazioni di attesa registrate usano anche il pool di thread. Le funzioni di callback vengono accodate al pool di thread.
Esiste un pool di thread per processo. A partire da .NET Framework 4, le dimensioni predefinite del pool di thread per un processo dipendono da diversi fattori, ad esempio le dimensioni dello spazio indirizzi virtuale. Un processo può chiamare il GetMaxThreads metodo per determinare il numero di thread. Il numero di thread nel pool di thread può essere modificato usando il SetMaxThreads metodo . Ogni thread usa le dimensioni dello stack predefinite e viene eseguito con la priorità predefinita.
Note
Il codice non gestito che ospita il framework di .NET può modificare le dimensioni del pool di thread usando la funzione CorSetMaxThreads, definita nel file mscoree.h.
Il pool di thread fornisce nuovi thread di lavoro o thread di completamento di I/O su richiesta fino a raggiungere il massimo per ogni categoria. Quando viene raggiunto un valore massimo, il pool di thread può creare thread aggiuntivi in tale categoria o attendere il completamento di alcune attività. A partire da .NET Framework 4, il pool di thread crea ed elimina i thread di lavoro per ottimizzare la velocità effettiva, definita come numero di attività completate per unità di tempo. Un numero eccessivo di thread potrebbe non usare in modo ottimale le risorse disponibili, mentre un numero eccessivo di thread potrebbe aumentare la contesa delle risorse.
Note
Quando la domanda è bassa, il numero effettivo di thread del pool può scendere sotto i valori minimi.
È possibile usare il GetMinThreads metodo per ottenere questi valori minimi.
Caution
È possibile usare il SetMinThreads metodo per aumentare il numero minimo di thread. Tuttavia, l'aumento inutilmente di questi valori può causare problemi di prestazioni. Se troppe attività iniziano contemporaneamente, tutte potrebbero sembrare lente. Nella maggior parte dei casi il pool di thread avrà prestazioni migliori con il proprio algoritmo per l'allocazione dei thread.
Metodi
| Nome | Descrizione |
|---|---|
| BindHandle(IntPtr) |
Obsoleti.
Associa un handle del sistema operativo all'oggetto ThreadPool. |
| BindHandle(SafeHandle) |
Associa un handle del sistema operativo all'oggetto ThreadPool. |
| GetAvailableThreads(Int32, Int32) |
Recupera la differenza tra il numero massimo di thread del pool di thread restituiti dal GetMaxThreads(Int32, Int32) metodo e il numero attualmente attivo. |
| GetMaxThreads(Int32, Int32) |
Recupera il numero di richieste al pool di thread che possono essere attive contemporaneamente. Tutte le richieste sopra quel numero rimangono in coda fino a quando i thread del pool di thread non diventano disponibili. |
| GetMinThreads(Int32, Int32) |
Recupera il numero minimo di thread creati dal pool di thread su richiesta, man mano che vengono effettuate nuove richieste, prima di passare a un algoritmo per la gestione della creazione e della distruzione del thread. |
| QueueUserWorkItem(WaitCallback, Object) |
Accoda un metodo per l'esecuzione e specifica un oggetto contenente dati da utilizzare dal metodo . Il metodo viene eseguito quando diventa disponibile un thread del pool di thread. |
| QueueUserWorkItem(WaitCallback) |
Accoda un metodo per l'esecuzione. Il metodo viene eseguito quando diventa disponibile un thread del pool di thread. |
| QueueUserWorkItem<TState>(Action<TState>, TState, Boolean) |
Accoda un metodo specificato da un Action<T> delegato per l'esecuzione e fornisce i dati da usare dal metodo . Il metodo viene eseguito quando diventa disponibile un thread del pool di thread. |
| RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean) |
Registra un delegato per attendere un oggetto WaitHandle, specificando un intero con segno a 32 bit per il timeout in millisecondi. |
| RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean) |
Registra un delegato per attendere un oggetto WaitHandle, specificando un intero con segno a 64 bit per il timeout in millisecondi. |
| RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean) |
Registra un delegato per attendere un WaitHandleoggetto , specificando un TimeSpan valore per il timeout. |
| RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean) |
Registra un delegato per attendere un oggetto WaitHandle, specificando un intero senza segno a 32 bit per il timeout in millisecondi. |
| SetMaxThreads(Int32, Int32) |
Imposta il numero di richieste al pool di thread che possono essere attive contemporaneamente. Tutte le richieste sopra quel numero rimangono in coda fino a quando i thread del pool di thread non diventano disponibili. |
| SetMinThreads(Int32, Int32) |
Imposta il numero minimo di thread creati dal pool di thread su richiesta, in quanto vengono effettuate nuove richieste, prima di passare a un algoritmo per la gestione della creazione e della distruzione del thread. |
| UnsafeQueueNativeOverlapped(NativeOverlapped*) |
Accoda un'operazione di I/O sovrapposta per l'esecuzione. |
| UnsafeQueueUserWorkItem(WaitCallback, Object) |
Accoda il delegato specificato al pool di thread, ma non propaga lo stack di chiamate al thread di lavoro. |
| UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean) |
Registra un delegato per attendere un oggetto WaitHandle, usando un intero con segno a 32 bit per il timeout in millisecondi. Questo metodo non propaga lo stack di chiamate al thread di lavoro. |
| UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean) |
Registra un delegato per attendere un oggetto WaitHandle, specificando un intero con segno a 64 bit per il timeout in millisecondi. Questo metodo non propaga lo stack di chiamate al thread di lavoro. |
| UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean) |
Registra un delegato per attendere un WaitHandleoggetto , specificando un TimeSpan valore per il timeout. Questo metodo non propaga lo stack di chiamate al thread di lavoro. |
| UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean) |
Registra un delegato per attendere un oggetto WaitHandle, specificando un intero senza segno a 32 bit per il timeout in millisecondi. Questo metodo non propaga lo stack di chiamate al thread di lavoro. |
Si applica a
Thread safety
Questo tipo è thread-safe.