Introduzione
Nel post precedente
abbiamo visto come utilizzare la classe Thread in modo basilare. In
breve: come creare un nuovo thread, utilizzando le classi ThreadStart e ParameterizedThreadStart, a
seconda del fatto che il metodo da eseguire in modo asincrono abbiamo parametri
oppure no.
Quello che vediamo oggi va un po' più in là. Sarà un po' tutto teorico,
perchè francamente non ho mai avuto bisogno di scendere così nel dettaglio.
Innanzitutto il Framework ci mette a disposizione la classe ThreadPool. Questa classe è
definita come static, di conseguenza non abbiamo bisogno di istanziarla per
poterla utilizzare. Come dice la pagina su MSDN, la classe ThreadPooo...
Provides a pool of threads that can be used to post work items, process
asynchronous I/O, wait on behalf of other threads, and process timers.
Direi che è tutto abbastanza chiaro. Attraverso il metodo QueueUserWorkItem, possiamo
richiedere al pool di thread la creazione di un nuovo thread che - ovviamente -
giri in modo asincrono. Tutti i thread gestiti all'interno di ThreadPool hanno
la property IsBackground = true. Una cosa importante da sottolineare è che la chiamata al
metodo QueueUserWorkItem ritorna true se il thread è
stato accodato al pool, oppure false se qualcosa non è
andato bene (in tal caso, verrà sollevata un eccezione di tipo ApplicationException). Il metodo specificato nel
costruttore inoltre non viene eseguito immediatamente, ma viene eseguito quando
diventa disponibile il pool.
Nell'ultimo post avevo parlato di un'applicazione creata
apposta per studiare questo argomento. In questa applicazione avevo implementato
un semplice metodo aggiungiRecord per inserire qualche migliaio di
record dentro una tabella di SQL Server, e lo avevo fatto girare in modo
asincrono facendomi avvisare alla fine. Vediamo come ottenere lo stesso
risultato con il pool di thread.
WaitCallback clk = new WaitCallback(aggiungiRecord);
bool ret = ThreadPool.QueueUserWorkItem(new WaitCallback(aggiungiRecord));
Il codice qui sopra istanzia un oggetto WaitCallback, da usare nella
chiamata al metodo QueueUserWorkItem. La classe WaitCallback
espone due proprietà interessanti: Method e
Target. La prima è un'istanza della classe MethodInfo che ci permette (tramite
Reflection) di analizzare a run-time il metodo che sta per essere eseguito in
modo asincrono nel ThreadPool. La seconda proprietà invece è un riferimento
all'object nel quale ci troviamo: nel mio caso, trattandosi di un Button, tale
object è la Windows Forms relativa.
La seconda riga di codice non fa altro
che richiedere l'inserimento all'interno del ThreadPool dell'oggetto
WaitCallback. Salvo il risultato in una variabile bool per controllare che tutto
sia andato regolarmente.
Metodi interessanti del ThreadPool
La classe
ThreadPool espone alcuni metodi interessanti. Il metodo GetAvaiableThreads ritorna il
numero di thread disponibili all'interno del thread. Esiste un pool di
thread per ogni processo. Per default, il numero di thread disponibili per ogni
pool è 25. E' possibile cambiare il numero di thread attraverso i metodi
SetMaxThreads e SetMinThreads.
Mi sento di consigliare inoltre la lettura di questo articolo su MSDN che tratta in modo esauriente questo
argomento.
powered by IMHO 1.3