Reactive Extensions – Play .NET

Navegando por la web de Silverlight me encontré con esta librería, Reactive Extensions (Rx), que como dice en su propia página, nos permite desarrollar aplicaciones basadas en eventos y con operaciones asíncronas utilizando secuencias observables y operadores LINQ.

Rx se compone de :

  • Tipos que permiten representar flujos de datos asíncronos (Observables)
  • Operadores que nos permiten consultar esos flujos de datos asíncronos (Linq)
  • Tipos para parametrizar concurrencia (Scheduler)

Entre todo lo que aporta Rx, en esta entrada trataré su uso en contraposición a los eventos clásicos de .NET. En primer lugar, detallaré la diferencias entre ambos. La siguiente tabla muestra los aspectos más básicos de las dos alternativas: declaración, publicación, y suscripción:

Play .NET - Rx vs Eventos

Rx vs Eventos

En este aspecto ambos métodos son similares y a priori Rx no aporta ningún beneficio respecto a los eventos. Pero vamos a ver cómo Rx mejora a los eventos.

Separación entre suscripción y publicación

Los Subjects, que hemos visto antes, tiene dos operaciones publicar y suscribirse. La clase Subject implementa dos interfaces, IObserver, que permite enviar mensajes a todos los subscriptores, e IObservable que contiene un método de subscripción. Ambas interfaces pertenecen al espacio de nombres System. De esta manera conseguimos tener por un lado suscriptores, y por otro, publicadores, algo que no es posible realizar con los eventos de .NET en los que tenemos que tener acceso al evento para suscribirnos a él.

Eventos como objetos de primera clase

Otro aspecto interesante que aporta Rx, es que nos permite tratar eventos como objetos de primera clase, es decir, que se pueden almacenar en variables, se pueden pasar como parámetros a métodos y se pueden crear en tiempo de ejecución. Un escenario, en el que esta posibilidad nos facilita enormemente las cosas, es cuando necesitamos mostrar información de log de una operación concreta. Con Rx podemos crear una instancia de subject, subscribirnos a ella (y que lance un operación cuando reciba la notificación) y pasárselo a una operación como parámetro para que vaya mandando sus notificaciones.

Mejora en el proceso de notificación

Con los eventos de .NET no tenemos la posibilidad de saber si todos los suscriptores han recibido una notificación o si ha saltado alguna excepción durante el proceso de notificación. Rx sí nos ofrece esta posibilidad a través de la interfaz IObserver, que implementa la clase Subject, que contiene dos métodos además de OnNext, llamados OnError(Exception exc) y OnCompleted(). El primero de ellos, se lanzará en caso
Además utilizar Rx nos facilita el control de flujo de datos, ya que en una ejecución en la que se esté continuamente notificando, mediante llamadas al método OnNext, no se lanzará una nueva notificación hasta que el evento OnCompleted de la notificación anterior se haya lanzado, impidiendo que notificaciones se superpongan.

subject.Subscribe(x => Console.WriteLine("Hola"),
exc => Console.WriteLine(exc.Message),
() => Console.WriteLine("Subscriptores notificados"));

Anular suscripciones

La forma en la que anulamos la subscripción también varía en Rx con respecto a los eventos de .NET. A diferencia de éstos últimos en los que utilizando el operador -= podemos eliminar el registro a un evento, en Rx no existe un método análogo, no existe un Unsubscribe. En su lugar, Rx al llamar el método Subscribe devuelve un objeto que implementa la interfaz IDisposable, con el que, llamando al método Dispose, eliminamos la referencia. El beneficio de este método es que nos evitamos tener que guardar la referencia de lo que queremos ejecutar al recibir una notificación para eliminar la suscripción, simplificando así proceso.

Operaciones sobre flujos de datos

Entre los componentes de Rx, se incluían una serie de operadores para realizar operaciones sobre flujos de datos asíncronos, esto es, Linq. Destaco algunas que me han parecido interesantes:

  • Filtrado. El uso de operadores Linq nos permite filtrar notificaciones. En este método que nos hace de wrapper para suscribirnos, se señala una condición por la que filtrar notificaciones, si el valor pasado como parámetro en el OnNext no es igual al pasado como parámetro en la suscripción, el subscriptor no recibirá ninguna notificación.
subject.Where(val => val == code).Subscribe(action)

  • Transformación previa a la notificación. Mediante el operador Select, podemos tomar como parámetro el valor del parámetro del método OnNext y hacer realizar operaciones con él previas a la notificación.
subject.Select(Convert).Subscribe(action);

  • Delay. Podemos retrasar las notificaciones un tiempo, a través del operador Delay. En este ejemplo, se retrasan las notificaciones un segundo desde que se lanzan.
subject.Delay(TimeSpan.FromSeconds(1)).Subscribe(action);

  • Buffer. Permite almacenar todas las notificaciones recibidas durante un periodo de tiempo especificado, permitiéndonos manejar datos estadísticos por ejemplo. En esta línea de código se envían el número de notificaciones lanzadas (llamadas al método OnNext) en 5 segundos.
subject.Buffer(TimeSpan.FromSeconds(5)).Select(list => list.Count).Subscribe(act);
En la siguiente entrada desarrollaré un proyecto de ejemplo donde podré en práctica algunos de los conceptos incluidos en este post. 
Anuncios
Esta entrada fue publicada en .NET y etiquetada , , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s