miércoles, 13 de julio de 2016

Receta Multithreading en C# No. 5-8: Diseño Tipo Awaitable Personalizado

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 Especificación de C# 5.0 para tipos awaitable personalizados
5.2 Interfaz InotifyCompletion
Conclusiones
Literatura & Enlaces

1. Introducción

Con esta receta C# se desea ilustrar cómo crear un tipo awaitable personalizado compatible con el operador asincrónico await. Más que de una aplicación concreta, el propósito es ilustrar en sentido académico cómo el programador puede crear una implementación personalizada de un tipo awaitable. Se describen los requerimientos para la definición de un tipo awaitable personalizado siguiendo la especificación del parágrafo 7.7.7.1 de la versión de C# 5.0. La sección práctica recurre al uso de la interfaz INotifyCompletion para la calendarización de continuaciones cuando el tipo await personalizado haya finalizado.

2. Palabras Clave

  • Await
  • Continuación
  • Interfaz
  • INotifyCompletion

3. Problema

Crear una implementación personalizada de un awaitable compatible con la función asincrónica await.

4. Solución

En .NET Framework se cuenta con la interfaz INotifyCompletion para el diseño de un tipo awaitable personalizado.

5. Discusión de la Solución

5.1 Especificación de C# 5.0 para tipos awaitable personalizados

En el parágrafo 7.7.7.1 (Agafonov, 2013) se definen los requerimientos para la definición de expresiones awaitable

Una expresión t es awaitable si se respeta cualquiera de estas reglas: 
  • La expresión t es un tipo de dato dynamic en tiempo de compilación. 
  • La expresión t tiene un método de instancia o método de extensión llamado GetAwaiter() sin parámetros regulares o tipos paramétricos y un tipo de retorno X que debe cumplir estas especificaciones: 
    • X debe implementar la interfaz System.Runtime.CompilerServices.INotifyCompletion (INotifyCompletion Interface", 2016).
    • X cuenta con una propiedad de sólo lectura pública de tipo bool llamada IsCompleted.
    • X cuenta un método de instancia público sin parámetros regulares ni paramétricos llamado GetResult().
Esta descripción está basada en la lectura del documento de especificación del lenguaje de programación C# que el lector puede encontrar en este enlace: CSharp 5.0 Language Specification.pdf.

Esta especificación se sigue en la sección práctica de esta receta para el diseño de un tipo awaitable personalizado.

5.2 Interfaz INotifyCompletion

La interfaz INotifyCompletion (namespace System.Runtime.CompilerServices) representa una operación que programa continuaciones una vez que finaliza su ejecución.

6. Práctica: Diseño de Tipo Awaitable Personalizado

Esta receta sigue el parágrafo 7.7.7.1 de la especificación de C# 5.0.

En primer lugar se implementa el tipo awaitable personalizado: 

La clase AwaitablePersonalizado (líneas 6-31) representa la implementación del tipo awaitable personalizado. De acuerdo a la especificación de C# 5.0, esta clase escribe el método GetAwaiter() (líneas 27-30); además retorna el tipo que implementa la interfaz INotifyCompletion: AwaiterPersonalizado.




Continuando, la clase AwaiterPersonalizado (líneas 11-77) implementa la interfaz INotifyCompletion. Estas son las características de esta clase: 
  • Líneas 25-28: Propiedad pública de sólo lectura IsCompleted para determinar si la ejecución de la operación ha finalizado.
  • Líneas 43-46: Método GetResult() que retorna el resultado de la operación.
Por último con la clase PersonalizacionAwait prueba el tipo awaitable personalizado: 

Archivo C# PersonalizacionAwait.cs [Enlace alternativo][Enlace alternativo]: 

En las líneas 24-33 se llevan a cabo estas operaciones: 
  • Línea 26: Se crea un objeto del tipo awaitable personalizado para ejecución sincrónica.
  • Línea 27: Se usa el operador await sobre el tipo awaitable personalizado.
  • Línea 28: Se muestra en la salida estándar el resultado de la ejecución sincrónica.
  • Línea 30: Creación de objeto de tipo AwaitablePersonalizado para ejecución asincrónica.
  • Línea 31: Uso operación asincrónica await para invocación asincrónica.
  • Línea 32: Muestra en la salida estándar el resultado de la operación asincrónica.
Prueba de ejecución: 

7. Conclusiones

Se ha demostrado como en C# es posible crear un tipo awaitable personalizado para operar con la función asincrónica await. Este conocimiento debe alentar al programador a incursionar o sentir curiosidad por temas avanzados que pueden tratarse con C#.


La última receta multithreading de esta serie Usando C# 5.0 enseña al programador a usar el operador asincrónico await con el tipo dynamic.

8. Literatura & Enlaces

Agafonov, E. (2013). Multithreading in C# 5.0 Cookbook. United States: Packt Publishing.
INotifyCompletion Interface (System.Runtime.CompilerServices) (2016, julio 13). Recuperado desde https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.inotifycompletion(v=vs.110).aspx


O

No hay comentarios:

Publicar un comentario

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