miércoles, 9 de diciembre de 2015

Hilos con C#, Tasks, Task -T-

Colocar un trabajo en una cola de hilos puede ser util pero tiene algunos defectos. No hay una forma pre-construida que permita conocer cuando la operación a terminado  y cuando ésta ha regresado un valor.

.NET Framework introduce el concepto de Task, que es un objeto que representa algún trabajo que debería ser realizado. El objeto Task puede decirle si el trabajo a sido completado y si la operación a regresado un resultado.

Un task scheduler es responsable de iniciar y manejar al objeto Task. Por omisión el programador de tareas usa hilos desde el pool de hilos para ejecutar la tarea Task.

Las tareas pueden ser usadas para hacer o mantener su aplicación receptiva. Si el hilo que administra la interfaz del usuario descarga el trabajo en otro hilo desde el pool de hilos, este puede mantener procesando eventos de usuario y asegurar que la aplicación puede permanecer en uso. Pero esto no le ayuda con la escalabilidad. Si un hilo recibe una solicitud web, este podría iniciar una nueva tarea, este podría consumir otro hilo desde el pool de hilos mientras que espera resultados.

Ejecutar una tarea Task en otro hilo permite mantener receptiva la aplicación de usuario. Misma que puede ser manejada en otro hilo, o bien hacer paralelo su trabajo en múltiples procesadores.

Ejemplo de como iniciar una nueva tarea Task y esperar hasta que esta termine. En este ejemplo se crea una tarea que inicia de inmediato. La llamada a Wait es equivalente al uso de Join. Este espera hasta que la tarea Task es finalizada antes de salir de la aplicación.

using System;
using System.Threading.Tasks;

namespace StartingNewTask
{
    class Program
    {
        static void Main(string[] args)
        {
            Task tarea = Task.Run( () => 
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("Tarea en ejecución {0}", i);
                }
            } );

            tarea.Wait();
        }
    }
}

Además de Task, el .NET Framework tambien tiene una clase Task<T> que es posible utilizar cuando deba regresar un valor, como se ve en el siguiente ejemplo.

using System;
using System.Threading.Tasks;

namespace UsingTaskReturnValue
{
    class Program
    {
        static void Main(string[] args)
        {
            Task<string> tarea = Task.Run(() => { return "Hilo regresando un valor"; });

            Console.WriteLine(tarea.Result); // presenta
        }
    }
}


Intentar leer la propiedad Result en una tarea forzará al hilo a intentar leer el resultado esperando    que la tarea sea terminada antes de continuar. Mientras la tarea no sea terminada es imposible dar el resultado. Si la tarea no esta finalizada, este llamará el bloque del hilo en curso.


Referencia:
Exam Ref 70-483 Programming in C#

No hay comentarios.:

Publicar un comentario