Extensiones reactivas para .NET (Rx)
Publicación del inglés original: Miércoles, 18 de noviembre de 2009 a las 20:05 PST por Somasegar
Estoy encantado de anunciar una vista previa de las Extensiones Reactivas para .NET (Rx) en DevLabs de MSDN.
Con Rx, los programadores pueden escribir código declarativo conciso para orquestar y coordinar programas asíncronos y basados en sucesos con las expresiones patrones de .NET. Rx tiene una gran base teórica basada en la dualidad entre los modelos de diseño clásicos Iterador y Observador para simplificar y controlar la asincronía. Combinando la expresividad de LINQ con la elegancia de la teoría de categoría, Rx permite a los programadores escribir código asíncrono sin realizar actos crueles y poco naturales.
Como el nombre implica, los programas reactivos reaccionan a los cambios en su entorno. Tradicionalmente, los programadores utilizar bloqueos y los controladores de eventos para coordinar estos cambios. Rx modela cálculos asíncronos y eventos como colecciones basadas en inserción u observables, expandiendo por tanto el ámbito de los métodos de extensión más allá de las colecciones basadas en extracción, o enumerables, familiares en el territorio de la programación reactiva y los operadores de secuencia estándar de LINQ.
Práctico y pragmático
Las extensiones reactivas para .NET son un conjunto de métodos de extensión y una implementación de los operadores de secuencia estándar de LINQ para los nuevos interfaces IObservable <out T> e IObserver <in T> en .NET 4 y Silverlight 4. Las interfaces observables se han agregado a .NET para proporcionar una interfaz común para las notificaciones basadas en inserción que otras bibliotecas y características de .NET pueden reutilizar. Rx se centra en la coordinación y orquestación de cálculos basados en sucesos y cálculo asíncrono y aprovecha la nueva biblioteca Task Parallel como mecanismo de simultaneidad subyacente.
Las extensiones reactivas pueden utilizarse desde cualquier lenguaje .NET. En F #, los eventos de .NET son valores de primera clase que implementan la interfaz IObservable <out T>. Además, F # proporciona un conjunto básico de funciones para redactar colecciones observables y los programadores de F# pueden aprovechar Rx para obtener un conjunto más rico de operadores para redactar los eventos y otras colecciones observables.
El Kit de herramientas de Silverlight utiliza Rx para el funcionamiento del Drag and Drop Framework del kit de herramientas de Silverlight, un subconjunto de las API de WPF para iniciar e interactuar con operaciones de arrastre. El Drag and Drop Framework agrega compatibilidad con arrastrar y colocar a controles básicos, como TreeView, DataGrid, ListBox. Rx reduce drásticamente el tiempo de desarrollo al permitir operaciones de arrastrar, que son secuencias de eventos de usuario, ser descritas declarativamente. Silverlight crea elementos visuales de forma asíncrona y como resultado suele ser necesario escribir código de prueba asíncrono para asegurarse de que se ha creado correctamente un componente. La adición de recepción para el marco de pruebas de unidades de Silverlight permite a los programadores escribir pruebas basadas en eventos confiables sin sacrificar la legibilidad.
Muéstrame código
El ejemplo siguiente muestra un sencillo programa reactivo de estilo AJAX que traduce a inglés mediante el servicio de traducción Bing y muestra los resultados.
El campo de entrada en la página se expone como una colección de cadenas observable que genera un valor siempre que el usuario deja de escribir durante medio segundo. El método de extensión GetKeyUpEvents expone el evento estándar de .NET KeyUp como una colección observable.
IObservable<string> words = (from keyup in Input.GetKeyUpEvents() select Input.Value).Throttle(TimeSpan.FromSeconds(.5))
Para obtener acceso al servicio de traducción Bing, simplemente hemos convertir una referencia de servicio WCF que utiliza el estándar BeginInvoke y EndInvoke de .NET o el modelo asincrónico basado en eventos a una función que devuelve una colección observable singleton a través de una de las funciones auxiliares estándar que Rx proporciona.
IObservable<TranslationResponse> Translate(this string text, string sourceLanguage, string destinationLanguage){…}
La coordinación entre los diversos cálculos utiliza una consulta LINQ que envía solicitudes al servicio de traducción Bing para traducir cada palabra en holandés, francés y español y espera a los dos primeros de tres resultados para volver mediante un modelo de combinación.
var translations = from word in words
let dutch = Bing.Translate(word, "en", "nl")
let french = Bing.Translate(word, "en", "fr")
let spanish = Bing.Translate(word, "en", "es")
from results in Observable.Join
( dutch.And(spanish).Then((d, s) =>
new { Dutch = d, French = Bing.NoResult, Spanish = s })
, dutch.And(french).Then((d, f) =>
new { Dutch = d, French = f, Spanish = Bing.NoResult })
, french.And(spanish).Then((f, s) =>
new { Dutch = Bing.NoResult, French = f, Spanish = s })
).Until(words)
select results;
Por último, nos suscribimos a los resultados de las traducciones y actualizamos la interfaz de usuario una vez que se ha notificado un cambio.
translations.Subscribe(result =>
{
Dutch.InnerText = result.Dutch.GetTranslatedTerm();
French.InnerText = result.French.GetTranslatedTerm();
Spanish.InnerText = result.Spanish.GetTranslatedTerm();
});
Los desarrolladores no necesitan preocuparse acerca de cómo ejecutar la suscripción en el subproceso correcto; el motor en tiempo de ejecución de Rx se ocupa de ello.
Material de bonificación
Además de los métodos de extensión en colecciones observables, Rx también contiene un número de tipos y espacios de nombres que implementan algunos de los nuevos métodos de extensión para las colecciones observables sobre colecciones enumerables y un puerto de espera de PLINQ para .NET 3.5 están disponibles para que los desarrolladores puedan experimentar.
Juguemos
Puede Descargar Rx (en inglés) desde DevLabs. Díganos lo que piensa en el foro del proyecto (en inglés) y eche un vistazo a los vídeos y screencasts de Channel 9 (en inglés).
¡Namaste!