lunes, 27 de junio de 2016

Receta Multithreading en C# No. 5-3: Uso Operador await en Tareas Asincrónicas Subsecuentes

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Implementación con TPL
5.2 Implementación con el operador asincrónico async
6. Práctica: TPL vs Operador Asincrónico await en Tareas Asincrónicas
Conclusiones
Literatura & Enlaces

1. Introducción

Es momento de comprender qué ocurre con las llamadas consecutivas a tareas asincrónicas con el operador asincrónico await. Esta receta explica la forma de leer el flujo de control de invocaciones de operaciones asincrónicas tanto de una implementación con TPL y otra con el operador asincrónico await para finalmente concluir cuál de los dos enfoques es el más práctico.

2. Palabras Clave

  • Asincronismo
  • await
  • Flujo de control
  • Operador asincrónico
  • Sincronismo
  • TPL

3. Problema

Analizar el flujo de control de tareas asincrónicas subsecuentes tanto con el enfoque de TPL y uso del operador asincrónico await.

4. Solución

Para la solución de este problema se escriben dos métodos:
  1. Con construcciones de TPL -objetos Task y continuaciones.
  2. Con operador asincrónico await.

5. Discusión de la Solución

5.1 Implementación con TPL

Para definir una implementación con TPL se recurre al uso de continuaciones a partir de una tarea compuesta. Esta tarea compuesta cuenta con declaraciones de otro objetos Task anidadas, que al mismo tiempo definen un esquema de respuesta a casos de éxito y fallo a través de continuaciones.

5.2 Implementación con el operador asincrónico await

Este operador simplifica la invocación de operaciones asincrónicas usando elementos del lenguaje para la obtención de resultados, gestión de excepciones y el flujo de control del programa.

6. Práctica: TPL vs Operador Asincrónico await en Tareas Asincrónicas Subsecuentes

Este ejemplo es una adaptación del código presentado por Aganof (2016): presenta una implementación del flujo de control de operaciones asincrónicas en TPL y con la función asincrónica await.

El método ObtenerInfoThreadAsync(string) (líneas 86-103) lleva a cabo las siguientes operaciones: 
  • Línea 88: Muestra el nombre de la fuente desde donde se invocó este método.
  • Línea 91: Simula la ejecución de una operación de duración extendida.
  • Líneas 93-96: Lanza una excepción intencionada cuando el nombre de la fuente es "TPL No. 2".
  • Líneas 98-102: Retorna información del thread de ejecución para esta operación asincrónica.
Método AsincronismoConTpl() (líneas 26-58): 
  • Líneas 28-53: Definición de tarea compuesta.
    • Línea 30: Definición y asociación de objeto Task con el método ObtenerInfoThreadAsync().
    • Líneas 35-44: Definición de un nuevo objeto Task anidado, además de continuaciones para los casos de éxito y excepción.
    • Líneas 49-52: Continuación para objeto Task tarea1.
  • Línea 55: Inicio de la ejecución de la tarea compuesta.
Método AsincronismoConAwait() (líneas 65-78): 
  • Líneas 67-73: Bloque try para la invocación lineal/sincrónica de ObtenerInfoThreadAsync() a través del operador asincrónico await.
  • Líneas 74-77: Bloque catch para responder a excepciones que eventualmente se produzcan durante la ejecución de las operaciones invocadas con await.
Hay que notar que en el caso de AsincronismoConAwait() ambas invocaciones se realizarán una tras otra, es decir de modo secuencial -i.e., sincrónicamente. Mientras que en AsincronismoConTpl() se requiere de una mayor complejidad -tareas anidadas, continuaciones y definiciones para responder a casos de falla y éxito.

Otro punto relevante en este caso es que el programa da la impresión de tratarse de una implementación de sincronismo, sin embargo al remover las llamadas a Wait() en el método Ejecutar() (líneas 12-19), se puede pensar que las llamadas a AsincronismoConAwait() y AsincronismoConTpl() son tareas asincrónicas y que Ejecutar() puede ejecutar otras expresiones mientras que éstos dos terminan. Wait() sólo se ha usado en este caso para demostrar la diferencia de implementación de estos dos enfoques.

La siguiente captura de vídeo demuestra lo que sucede con la invocación de los dos métodos anterior: 


En este enlace de GitHub puede encontrar la solución de Visual Studio 2015 y los proyectos asociados a esta receta y otras más: https://github.com/Fhernd/RecetasMultithreadingCSharp.

7. Conclusiones

Se demostró que una implementación de una operación asincrónico con el operador asincrónico await es mucho más elegante e intuitiva frente a una creada usando elementos de programa de TPL.

En la próxima receta multithreading se mostrará al programador cómo usar await en la ejecución en paralelo de operaciones asincrónicas.

8. Literatura & Enlaces

Agafonov, E. (2013). Multithreading in C# 5.0 Cookbook. United States: Packt Publishing.

V

No hay comentarios:

Publicar un comentario

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