Sigue a

Portada

Hace unas semanas escribí sobre un nuevo ORM ligero Oracle para .NET, desarrollado por Javier Torrecilla. El cual además contesto a diferentes preguntas que aproveche para hacerle.

Hoy tengo el placer de publicar un artículo de su autoría que hace una aproximación a las nuevas capacidades de programación asíncrona en la plataforma .NET.

Pero no solamente se queda en el análisis teórico, si no se arremanga las mangas para picar código de ejemplo que comparte con los lectores de GenbetaDev

Introducción


Desde las primeras versiones de .NET existe la posibilidad de ejecutar procesos asíncronos gracias al uso de Delegados. Si se necesitaba comprobar cuando había terminado el proceso, era necesario definir CallBacks para tratar con el resultado de dicho proceso.

Además de ello, aquellos que trabajamos con Windows Forms o WPF, para poder comunicar un proceso asíncrono con un control de la interfaz de usuario, el cual fue creado en otro hilo, es necesario que utilicemos this.Invoke o Dispatcher.Invoke (WPF) para realizar dicha comunicación.

Con .NET 4.0, llegó la Task Parallel Library, y la clase Task con objeto de manejar procesos u operaciones que van a requerir ser ejecutados de forma asíncrona.

Gracias a la clase Task se ganó mucha simplicidad a la hora de definir dichos procesos, y también para definir sus CallBacks gracias al método ContinueWith.

Además también se simplifico la comunicación con la UI, ya que se puede definir un parámetro de tipo TaskScheduller para evitarnos el uso de Invoke’s.

¿Qué es lo nuevo de .Net 4.5?


ASYNC
Async es un modificador que se va a aplicar a aquellos métodos que van a contener las acciones a realizar de manera asíncrona.

El hecho de que un método sea cualificado con ASYNC no indica que se vaya a ejecutar asíncronamente, para ello necesita la segunda palabra clave.

AWAIT
Await es un modificador de instrucción que va a indicar que dicha acción se tiene que realizar de manera asíncrona, por lo tanto, no se tendrán en cuenta las siguientes acciones hasta que dicha tarea haya finalizado. Cabe destacar que no bloquea el resto de acciones, sino que es como si definiera un CALLBACK para las líneas de código siguientes a AWAIT, y en el momento de finalizar el proceso asíncrono ejecutará dicho CALLBACK.

Para que una instrucción se pueda cualificar como await tiene que devolver un Tipo Task o Task.

Cancelación


Para que una tarea pueda ser cancelada, el método async debe tener un parámetro del tipo CancellationToken.

Si se invoca al método Cancel de nuestro objeto CancellationTokenSource, se considerará como el final de la tarea. Será necesario utilizar el método ThrowIfCancellationRequested , y también tendremos que tener un control de excepciones del tipo OperationCanceledException.

Nuevos Métodos Extensores TASK


Dentro del nuevo Framework se han incluido algunos métodos extensores, los cuales tienen bastantes posibilidades de ser métodos “normales” en la versión final, a tener en cuenta:
  • WhenAll: Este método se utiliza para “esperar” un conjunto de Tareas asíncronas. Una vez hayan finalizado todas, tendremos como resultado un array de tipo T.
  • WhenAny: Este método va a permitir obtener la primera tarea disponible (dado un conjunto de n tareas). Al contrario que WhenAll, va a devolver un tipo Task por lo que será necesario utilizar otro await para esperar el resultado de dicha tarea.

var t = await await Task.WhenAny ()
o
var t = await Task.WhenAny();
var result = await t;

En el momento en el que la primera termine podríamos hacer que el resto se cancelen gracias al CancellationToken.

  • FromResult: Este método va a crear un nuevo objeto de Tipo Task partiendo de un valor T dado.
  • Run: Devuelve una tarea a partir de una acción dada (Similar a Task.Factory.StartNew) Las tareas se encolaran en TheadPool
  • Delay: Sirve para introducir pausas en métodos asíncronos.
  • Yield: Sirve para permitir procesar otros mensajes
  • ConfigureAwait: Para aquellos procesos en los que realmente el contexto de retorno de una tarea no es significativo, podemos utilizar ConfigureAwait(false). El valor por defecto es True, si utilizamos configureAwait y queremos modificar un control de la Interfaz de Usuario, nos encontraremos con una excepción.

    Ejemplos


    Ejemplo Async / Await
    Ejemplo When any
    Ejemplo Async / Await con Cancel
    Ejemplo Async con await con Cancel
    Ejemplo WhenAny
    Ejemplo WhenAny
    Ejemplo WhenAll
    Ejemplo WhenAll

Los comentarios se han cerrado

Ordenar por:

3 comentarios