Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)
Una de las características mas interesantes de los delegados es que pueden ser invocados de manera asíncrona. La pega de los delegados es que hay que declararlos, y hacer una función para asignarla al delegado y luego ya podremos hacer la invocación asíncrona. Las ventajas de la invocación asíncrona respecto a crear un hilo explicitamente son varias: menor cantidad de código y sobre todo, que el hilo será un hilo de pool de hilos de .Net, con las ventajas para el rendimiento que esto lleva asociadas.
Muchas veces usamos delegados asícronos para dotar de asincronía a un método síncrono, pero el problema es que tenemos que crear toda la artilleria de un delegado. Una pega aparejada es que a las complejidades propias de la programación asíncrona, uniremos la menor legibilidad (los delegados son muy útiles pero no son precisamente legibles).
La solución pasa por usar un delegado anónimo de manera que podemos poner en línea el código que se ejecutará en otro hilo. El truco del almendruco es simplemente asignar el delegado anónimo a un tipo de delegado ThreadStart. Además esta técnica nos permite saber de manera muy sencilla, usando un delegado AsyncCallback y poniedolo en el primer parámetro de la llamada a BeginInvoke, cuando el hilo levantado ha teerminado su trabajo. Podemos usar el segundo parámetro del método BeginInvoke del delegado de tipo ThreadStart para pasar estado al delegado que se ejdutará cuando el hilo termine. Si no necesitamos ninguna de estas características podríamos pasar a null ambos argumentos.
Sin duda, una manera curiosa y útil en ocasiones de usar el pool de hilos.
Creo que con el siguiente código el asunto quedará claro:
using System;
using System.Threading;
namespace SimpleThreadStart
{
class Program
{
static void Main(string[] args)
{
ThreadStart ts =
delegate
{
Console.WriteLine("Los delegados anónimos son mágicos");
};
ts.BeginInvoke(ThreadCompleted, "ESTAD0");
//Dar tiempo a que el hilo haga su trabajo...
Console.WriteLine("Pulse una tecla para terminar...");
Console.ReadKey();
}
//Esta función se ejecuta cuando el hilo termina su trabajo.
static private void ThreadCompleted(IAsyncResult ar)
{
Console.WriteLine("Se completo el hilo creado mediante un delegado asincrono");
Console.WriteLine("El estado pasado fue {0}", (string)ar.AsyncState);
}
}
}
Espero que os resulte útil o al menos curioso.