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.

Published 6/8/2008 18:49 por Rodrigo Corral
Archivado en: ,
Comparte este post:
http://geeks.ms/blogs/rcorral/archive/2008/08/06/invocar-delegados-an-243-nimos-as-237-ncronamente-o-como-usar-el-pool-de-hilos-en-dos-l-237-neas-de-c-243-digo.aspx

Comentarios

# re: Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

Un articulo referido a esto muy bueno de un tipo muy bueno :-), para el que quiera profundizar en APM con C# y .NET

msdn.microsoft.com/.../cc163323.aspx

Saludos

Unai

Wednesday, August 06, 2008 7:52 PM por Unai

# re: Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

Hola Rodrigo!

El ejemplo es muy claro...pero te lanzo una pregunta, ¿Esta forma de utilizar delegados anónimos es válida también en C# 3.0? ¿O se podría hacer de otra forma aprovechando las expresiones lambda?

Un abrazo crack

JC's

Wednesday, August 06, 2008 10:34 PM por Juan Carlos González Martín

# re: Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

JC todo delegado se puede convertir en expresión lambda. Lo anterior quedaría como:

ThreadStart ts = () => Console.WriteLine("Las expresiones lambda no son mágicas, son pura lógica");

Wednesday, August 06, 2008 11:13 PM por Anonimo

# re: Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

@Unai: Interesante artículo, gracias por el aporte titán!!!

@JC y Anonimo: Como bien dice anónimo todo delegado se puede expresar como una lambda, no lo hice así porque el código en el que usé esa técnica es C# 2.0, pero sin duda aun queda más reducido. Gracias a los dos a uno por la idea y al otro por la solución.

Un saludo!!!

Wednesday, August 06, 2008 11:30 PM por Rodrigo Corral

# re: Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

@espinete: hombre, la respuesta es evidente. En un lenguaje sin delegados anónimos esta técnica no se puede implementar.

Un saludo!

Wednesday, August 13, 2008 10:12 PM por Rodrigo Corral

# re: Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

¿Pueden implantarse delegados en WCF? Lo pregunto porque es algo que no he visto y estoy diseñando un pool de objetos y ya tuve problemas con dynamic al consumir el servicio.

Wednesday, September 08, 2010 11:27 PM por phito