viernes, 25 de marzo de 2016

Receta Multithreading en C# No. 4-1: Cómo Crear una Tarea

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Clase Task
6. Práctica: Creación Múltiples Tareas
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

A partir de esta receta multithreading se da inicio a la serie de recetas dedicadas a la exploración de la librería Task Parallel Library (TPL). En la serie anterior -Uso de Pool de Threads-, se demostró un mecanismo de abstracción de uso de threads basado en la gestión eficiente de recursos del sistema -espacio de memoria y ciclos de procesador-. Este mecanismo permite centrar la atención del programador en la escritura de la lógica multithreading en lugar de la resolución de aspectos técnicos relacionados con el funcionamiento interno de ejecución de operaciones asincrónicas. Sin embargo, hay que considerar que este mecanismo no cuenta con una forma sencilla para la obtención de resultados de la ejecución de un thread en el pool de threads: el programar se debe de encargar de implementar el código que permita la obtención del resultado de la ejecución de una operación asincrónica; lo cual dificulta y hace más extenuante la tarea de crear paralelismo en una aplicación o proceso.


Al final de la serie anterior se elaboró una receta multithreading que explicó el modelo Event-based Asynchronous Pattern (EAP) que resuelven muchos aspectos técnicos relacionados con la ejecución de procesos asincrónicos: obtención de resultado al finalizar una operación asincrónica. De igual modo, con Asynchronous Programming Model (APM), este último aspecto de asincronismo es resuelto con relativa facilidad. Pero estos dos modelos carecen o comprenden un reto técnico la combinación de tareas asincrónicas para la resolución de un problema que demande la combinación de múltiples operaciones.


Para resolver el caso anterior, Microsoft .NET Framework creó una API dedicada y especializada para el manejo de operaciones asincrónicas que demanden obtención de resultados y combinación de acciones o tareas asincrónicas: Task Parallel Library. Esta librería se puede ver como otro nivel de abstracción para paralelismo: los detalles de bajo nivel son gestionados internamente, el programador no se ha de preocupar por la resolución de aspectos técnicos; además, esta librará provee un enfoque más conveniente para la escritura de aplicaciones con procesos asincrónicos que requieran un nivel de manipulación granular.


En C# 5.0 se cuenta con soporte nativo para el trabajo con Task Parallel Library. Para su uso, el programador deberá familiarizarse con dos nuevas palabras claves del lenguaje: await y async. Esto lleva al desarrollo a un conjunto de recetas que comprometen los siguientes temas:
  • Creación de una tarea
  • Ejecución de operaciones básicas en una tarea
  • Combinación de tareas
  • Conversión del patrón APM al enfoque basado en tareas
  • Conversión del patrón EAP al enfoque basado en tareas
  • Implementación de la cancelación de la ejecución de una tarea
  • Gestión de excepciones en tareas
  • Ejecución de tareas en paralelo
  • Ajuste y mejora de la ejecución de tareas con TaskScheduler

2. Palabras Clave

  • API
  • APM
  • EAP
  • Expresión lambda
  • Programación asincrónica
  • Programación multithreading
  • Tarea
  • Task Parallel Library
  • Thread
  • TPL

3. Problema

¿Cómo crear una tarea usando la librería Task Parallel Library (TPL)?

4. Solución

En el namespace System.Threading.Tasks se cuenta con la clase Task para la creación de tareas para operaciones o procesos asincrónicos.

5. Discusión de la Solución

5.1 Clase Task

La clase Task ("Task Class", 2016) representa una tarea (proceso o método) asincrónica. Con una instancia de esta clase se representa una tarea asincrónica que no retorna ningún valor.

Esta clase se introdujo a partir de la versión número 4 de Microsoft .NET Framework. Su propósito fue resolver mucho de los inconvenientes técnicos o dificultades para la combinación de operaciones asincrónicas y la obtención de resultados de operaciones asincrónicas presentados en los modelos EAP y APM.

También se pueden mencionar algunas ventajas técnicas frente a otros modelos de asincronismo -como Event-based Programming Model (EPM) y Asynchronous Programming Model-, como por ejemplo la consulta u obtención del estado de ejecución de una tarea a través de las propiedades:
  • Status
  • IsCanceled
  • IsCompleted
  • IsFaulted

5.3.1 Ejemplo básico de uso Task

En esta primer ejemplo básico de uso de Task se muestra el uso del método static Run para la ejecución de una tarea asincrónica representada en una expresión lambda:

En la línea 13 se invoca el método Run ("Task.Run Method", 2016), al cual se le pasa como argumento una expresión lambda. Esta expresión lambda (líneas 13-21) representa un ciclo que se ejecuta 1000001 veces. En la línea 25 con la invocación del método Wait ("Task.Wait Method", 2016) se indica que el método Main deberá de esperar hasta que la ejecución de la tarea que presenta el objeto Task -tarea- finalice su ejecución.


Compilación:

csc /t:exe UsoTask.cs


Ejecución assembly

.\UsoTask.exe


Demostración ejecución assembly (ideone.com): http://ideone.com/4wufiU


Demostración ejecución assembly (local): 
Ejecución assembly UsoTask.exe
Figura 1. Ejecución assembly UsoTask.exe.

6. Práctica: Creación Múltiples Tareas

En este ejemplo se demuestra cómo crear múltiples objetos Task y varios de los métodos que incorpora esta clase para la ejecución de operaciones asincrónicas.

En las líneas 13 y 14 se crean dos instancia de la clase Task. Las dos instancias reciben como argumento sobre el constructor una expresión lambda para la ejecución asincrónica del método TareaAsincronica. Con la invocación de Start sobre estos dos objetos Task, se da inicio a la ejecución asincrónica de TareaAsincronica.

Más adelante, con el método static Run se invoca TareaAsincronica. De manera análoga, con el uso del método static StartNew ("TaskFactory.StartNew", 2016) se crea  y se inicia la ejecución asincrónica de dos tareas asincrónica que referencian el método TareaAsincronica.

Casi al final, en la línea 28, se detiene la ejecución del método Main durante 1 segundo.

Por otra parte, el método TareaAsincronica (líneas 33-39) se muestra información del nombre de tarea en ejecución, el ID del thread y si éste se está ejecutando en el pool de threads.

Compilación: 

csc /t:exe TareasAsincronicas.cs

Ejecución assembly

.\TareasAsincronicas.exe

Demostración ejecución assembly (ideone.com): http://ideone.com/sdYXYR

Demostración ejecución assembly (local): 
Ejecución assembly TareasAsincronicas.exe
Animación 1. Ejecución assembly TareasAsincronicas.exe.

7. Conclusiones

Se dio inicio a la serie de recetas multithreading enfocadas al tratamiento de la librería Task Parallel Library (TPL). Esta librería provee un mecanismo más natural e intuitivo para el manejo de operaciones asincrónicas: obtención de resultados y combinación de operaciones asincrónicas.

La próxima receta multithreading demuestra cómo realizar acciones más avanzadas sobre una tarea.

8. Literatura & Enlaces

Agafonov, E. (2013). Multithreading in C# 5.0 Cookbook. United States: Packt Publishing.
Task Class (System.Threading.Tasks) (2016, marzo 25). Recuperado desde:
https://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx
Task.Run Method (Action) (System.Threading.Tasks) (2016, marzo 25). Recuperado desde: https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
Task.Wait Method (System.Threading.Tasks) (2016, marzo 25). Recuperado desde: https://msdn.microsoft.com/en-us/library/dd235635(v=vs.110).aspx
TaskFactory.StartNew Method (Action) (System.Threading.Tasks) (2016, marzo 25). Recuperado desde: https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspx


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.