Condividi tramite


ThreadPool Classe

Definizione

Fornisce un pool di thread che può essere usato per eseguire attività, inviare elementi di lavoro, elaborare operazioni di I/O asincrone, attendere per conto di altri thread ed elaborare timer.

public ref class ThreadPool abstract sealed
public ref class ThreadPool sealed
public static class ThreadPool
public sealed class ThreadPool
type ThreadPool = class
Public Class ThreadPool
Public NotInheritable 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, dorme per un secondo e quindi termina. Il ThreadProc metodo visualizza semplicemente un messaggio.

using namespace System;
using namespace System::Threading;

ref class Example
{
public:

   // This thread procedure performs the task.
   static void ThreadProc(Object^ stateInfo)
   {
      
      // No state object was passed to QueueUserWorkItem, so stateInfo is 0.
      Console::WriteLine( "Hello from the thread pool." );
   }
};

int main()
{
   // Queue the task.
   ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc));

   Console::WriteLine("Main thread does some work, then sleeps.");
   
   Thread::Sleep(1000);
   Console::WriteLine("Main thread exits.");
   return 0;
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
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 commenta 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 una condizione di razza.

Commenti

Molte applicazioni creano thread che impiegano molto tempo nello stato di sospensione, in attesa che si verifichi un evento. Altri thread possono immettere uno stato di sospensione solo per essere svegliati periodicamente per eseguire il polling per una modifica o aggiornare le informazioni sullo stato. Il pool di thread consente di usare i thread in modo più efficiente fornendo all'applicazione un pool di thread di lavoro gestiti dal sistema. Esempi di operazioni che usano thread del pool di thread includono quanto segue:

  • Quando si crea un Task oggetto o Task<TResult> per eseguire un'attività in modo asincrono, per impostazione predefinita l'attività viene pianificata per l'esecuzione in un thread del pool di thread.

  • I timer asincroni usano il pool di thread. I thread del System.Threading.Timer pool di thread eseguono callback dalla 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 metodo per accodare un metodo per l'esecuzione QueueUserWorkItem in un thread del pool di thread. A tale scopo, passare il metodo a un WaitCallback delegato. Il delegato ha la firma

    void WaitCallback(Object state)
    
    Sub WaitCallback(state As Object)
    

    dove state è un oggetto che contiene dati da usare dal delegato. I dati effettivi possono essere passati al delegato chiamando il QueueUserWorkItem(WaitCallback, Object) metodo .

Nota

I thread nel pool di thread gestiti sono thread in background. Vale a dire, le loro IsBackground proprietà sono true. Ciò significa che un ThreadPool thread non mantiene 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 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 rilevati 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 la coda.

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 la dimensione predefinita del pool di thread per un processo dipende da diversi fattori, ad esempio la dimensione dello spazio degli indirizzi virtuali. Un processo può chiamare il metodo GetMaxThreads 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 predefinite dello stack ed esegue con la priorità predefinita.

Nota

Il codice non gestito che ospita .NET Framework può modificare le dimensioni del pool di thread usando la CorSetMaxThreads funzione, definita nel file mscoree.h.

Il pool di thread fornisce nuovi thread di lavoro o thread di completamento di I/O su richiesta finché non raggiunge il massimo per ogni categoria. Quando viene raggiunto un 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 thread di lavoro per ottimizzare la velocità effettiva, definita come numero di attività completate per unità di tempo. Un numero troppo ridotto di thread potrebbe non usare in modo ottimale le risorse disponibili, mentre troppi thread potrebbero aumentare il conflitto per le risorse.

Nota

Quando la richiesta è bassa, il numero effettivo di thread del pool può scendere sotto i valori minimi.

È possibile usare il metodo GetMinThreads per ottenere questi valori minimi.

Attenzione

È possibile usare il SetMinThreads metodo per aumentare il numero minimo di thread. Tuttavia, un aumento non necessario di questi valori può provocare problemi di prestazioni. Se si avviano troppe attività contemporaneamente, potrebbero sembrare tutte lente. Nella maggior parte dei casi, il pool di thread offre prestazioni migliori con il proprio algoritmo per l'allocazione dei thread.

Proprietà

CompletedWorkItemCount

Ottiene il numero di elementi di lavoro che sono stati elaborati fino a questo momento.

PendingWorkItemCount

Ottiene il numero di elementi di lavoro attualmente in attesa di elaborazione.

ThreadCount

Ottiene il numero di thread del pool di thread attualmente esistenti.

Metodi

BindHandle(IntPtr)
Obsoleti.
Obsoleti.

Associa un handle del sistema operativo al ThreadPool.

BindHandle(SafeHandle)

Associa un handle del sistema operativo al ThreadPool.

GetAvailableThreads(Int32, Int32)

Recupera la differenza tra il numero massimo di thread del pool di thread restituito dal metodo GetMaxThreads(Int32, Int32) 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 al di fuori di tale numero rimangono in coda fino a quando non diventano disponibili thread di pool di thread.

GetMinThreads(Int32, Int32)

Recupera il numero minimo di thread che il pool di thread crea, man mano che vengono effettuate nuove richieste, prima di passare a un algoritmo per la gestione della creazione e dell'eliminazione del thread.

QueueUserWorkItem(WaitCallback)

Accoda un metodo da eseguire. Il metodo viene eseguito quando un thread del pool di thread diventa disponibile.

QueueUserWorkItem(WaitCallback, Object)

Accoda un metodo da eseguire e specifica un oggetto che contiene i dati che dovranno essere usati dal metodo. Il metodo viene eseguito quando un thread del pool di thread diventa disponibile.

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Accoda un metodo specificato da un delegato Action<T> per l'esecuzione e fornisce i dati che devono essere usati dal metodo. Il metodo viene eseguito quando un thread del pool di thread diventa disponibile.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Registra un delegato per l'attesa di un oggetto WaitHandle, specificando un valore intero con segno a 32 bit per il timeout in millisecondi.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int64, Boolean)

Registra un delegato per l'attesa di un oggetto WaitHandle, specificando un valore intero con segno a 64 bit per il timeout in millisecondi.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, TimeSpan, Boolean)

Registra un delegato per l'attesa di un oggetto WaitHandle, specificando un valore TimeSpan per il timeout.

RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, UInt32, Boolean)

Registra un delegato per l'attesa di 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 attivate contemporaneamente. Tutte le richieste al di fuori di tale numero rimangono in coda fino a quando non diventano disponibili thread di pool di thread.

SetMinThreads(Int32, Int32)

Imposta il numero minimo di thread che il pool di thread crea, man mano che vengono effettuate nuove richieste, prima di passare a un algoritmo per la gestione della creazione e dell'eliminazione del thread.

UnsafeQueueNativeOverlapped(NativeOverlapped*)

Accoda un'operazione di I/O sovrapposta per l'esecuzione.

UnsafeQueueUserWorkItem(IThreadPoolWorkItem, Boolean)

Accoda l'oggetto elemento di lavoro specificato nel pool di thread.

UnsafeQueueUserWorkItem(WaitCallback, Object)

Accoda il delegato specificato al pool di thread, ma non propaga lo stack di chiamata nel thread di lavoro.

UnsafeQueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Accoda un metodo specificato da un delegato Action<T> per l'esecuzione e specifica un oggetto che contiene i dati che dovranno essere usati dal metodo. Il metodo viene eseguito quando un thread del pool di thread diventa disponibile.

UnsafeRegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)

Registra un delegato per l'attesa di un WaitHandle, specificando 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 l'attesa di un oggetto WaitHandle, specificando un valore 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 l'attesa di un oggetto WaitHandle, specificando un valore TimeSpan 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 l'attesa di 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.

Vedi anche