martes, 19 de agosto de 2008

ThreadPool.QueueUserWorkItem

Si estas pensando en desarrollar una aplicación con procesamiento en paralelo una de las primeras opciones que deberías evaluar es el thread pool que proporciona el CLR de .net.

Esté es bastante útil sobre todo en escenarios simples o aquellos que no requieren sincronizar resultados y/o threads, el thread pool se encarga de crear y administrar los threads por lo cual no tendremos que agregar toda esta lógica a nuestra aplicación.
Aunque tiene bastantes ventajas como las ya comentadas también tiene limitantes como por ejemplo no es posible obtener el resultado de un elemento de trabajo como lo veremos mas adelante.

Para poder hacer uso del thread pool solo necesitas agregar el namespace System.Threading, crearte un método que cumpla con la firma del delegado System.Threading.WaitCallback y agendar su ejecución invocando el método QueueUserWorkItem del thread pool.

using System;
using System.Threading;

class test
{
    public static void Main(String[] args)
    {
        Console.WriteLine("thread id: " + Thread.CurrentThread.ManagedThreadId);
        ThreadPool.QueueUserWorkItem(CallbackMethod);
       //...
        Console.ReadKey();        
    }

    private static void CallbackMethod(Object state)
    {
        Console.WriteLine("thread id: " + Thread.CurrentThread.ManagedThreadId);
       //...
    }
}

Del ejemplo anterior podemos comentar lo siguiente: el thread pool es una clase estática por lo tanto existe solo un thread pool lo cual es una desventaja más.

QueueUserWorkItem recibe como parámetro un método que debe cumplir con la firma del delegado WaitCallback.

public delegate void WaitCallback(object state);

El método que pasamos como argumento será invocado por el thread pool via delegados y ejecutado en paralelo, decimos que se ejecuta en paralelo porque el thread principal encola nuestro método CallbackMethod que será invocado por otro thread mientras el thread principal continua ejecutando el resto del método Main, las salidas a consola nos ayudan a validar esto último escribiendo el thread id a consola.

El delegado WaitCallback define un parámetro de tipo Object debido a que nuestro método debe cumplir con esta firma se define dicho parámetro aún cuando no fue utilizado en este ejemplo.

No hay comentarios: