Este repositorio contiene cuatro bibliotecas que están conceptualmente relacionadas porque todas se ocupan de LINQ sobre secuencias de cosas:
Extensiones reactivas para .NET, también conocidas como Rx.NET o Rx (System.Reactive): una biblioteca para programación basada en eventos con un modelo declarativo y componible
AsyncRx.NET (vista previa experimental) (System.Reactive.Async): implementación experimental de Rx para IAsyncObservable<T>
que ofrece soporte async
/ await
más profundo
Extensiones interactivas para .NET, también conocidas como Ix (System.Interactive): operadores LINQ extendidos para IAsyncEnumerable
e IEnumerable
LINQ para IAsyncEnumerable
(System.Linq.Async): implementa operadores LINQ estándar para IAsyncEnumerable
Cada uno se describirá más adelante en este README.
La programación reactiva proporciona claridad cuando nuestro código necesita responder a eventos. Las bibliotecas Rx.NET se diseñaron para permitir que las aplicaciones nativas de la nube procesen datos en vivo de manera confiable y predecible.
Hemos escrito un libro GRATUITO que explica las abstracciones vitales que sustentan a Rx y muestra cómo explotar la poderosa y extensa funcionalidad integrada en las bibliotecas Rx.NET.
Basado en el libro de Lee Campbell de 2010 (donado amablemente al proyecto), se ha reescrito para actualizarlo con Rx.NET v6.0, .NET 8.0 y casos de uso nativos de la nube modernos, como IoT y aplicaciones reales. procesamiento de datos de flujo de tiempo.
Introducción a Rx.NET está disponible en línea, en GitHub, como PDF y EPUB.
Canal | receta | AsíncronoRx | Ix | Sistema.Linq.Async |
---|---|---|---|---|
NuGet.org | ||||
Vista previa de NuGet.org (si es más reciente que la versión) | ||||
Construir | Construido como parte de Ix | |||
Azur Artefactos | ||||
Historial de lanzamientos | Historial de lanzamientos | Historial de lanzamientos | Historial de lanzamientos |
Para compilaciones nocturnas, configure NuGet para usar esta fuente: https://pkgs.dev.azure.com/dotnet/Rx.NET/_packaging/RxNet/nuget/v3/index.json
Visítenos en el canal #rxnet en https://reactivex.slack.com/
En esta era digital, los flujos de datos en vivo son omnipresentes. Las aplicaciones financieras dependen de una respuesta rápida a la información oportuna. Las redes informáticas siempre han podido proporcionar amplia información sobre su estado y funcionamiento. Las empresas de servicios públicos, como los proveedores de agua, tienen una gran cantidad de dispositivos que monitorean sus operaciones. La interfaz de usuario y los marcos de creación de juegos informan las interacciones de los usuarios con gran detalle. Las furgonetas de reparto informan continuamente de su progreso. Los aviones proporcionan telemetría de rendimiento para detectar posibles problemas de mantenimiento antes de que se conviertan en problemas graves, y los automóviles ahora están empezando a hacer lo mismo. Muchos de nosotros usamos o llevamos dispositivos que rastrean nuestra actividad física e incluso nuestros signos vitales. Y las mejoras en el aprendizaje automático han enriquecido los conocimientos que se pueden derivar del volumen y la variedad cada vez mayores de datos en vivo.
Pero a pesar de estar tan extendidos, los flujos de información en directo siempre han sido algo así como ciudadanos de segunda clase. Casi todos los lenguajes de programación tienen alguna forma innata de trabajar con listas de datos (por ejemplo, matrices), pero estos mecanismos tienden a suponer que los datos relevantes ya están almacenados en la memoria, listos para que trabajemos con ellos. Lo que falta es vivacidad: el hecho de que una fuente de información pueda producir nuevos datos en cualquier momento, según su propio cronograma.
Rx eleva el soporte para transmisiones de información en vivo al mismo nivel que esperamos para cosas como matrices. He aquí un ejemplo:
var bigTrades = del comercio en intercambios donde trade.Volume > 1_000_000 select trade;
Esto utiliza la función LINQ de C# para filtrar trades
hasta aquellas entidades con un volumen superior a un millón. Esta sintaxis de expresión de consulta es solo una abreviatura de llamadas a métodos, por lo que también podríamos escribirla de esta manera:
var bigTrades = trades.Where(comercio => comercio.Volumen > 1_000_000);
El comportamiento exacto de estos dos fragmentos de código (equivalentes) depende del tipo trades
. Si fuera IEnumerable<Trade>
, entonces esta consulta simplemente recorrería la lista y bigTrades
sería una secuencia enumerable que contiene solo los objetos coincidentes. Si trades
fueran un objeto que representa una tabla de base de datos (por ejemplo, un DbSet de Entity Framework, esto se traduciría en una consulta de base de datos. Pero si usamos Rx, trades
serían un IObservable<Trade>
, un objeto que informa eventos en vivo a medida que ocurren). Y bigTrades
también sería un IObservable<Trade>
, que informaría solo aquellas operaciones con un volumen superior a un millón. Podemos proporcionarle a Rx una devolución de llamada para que la invoque cada vez que una fuente observable tenga algo. para nosotros:
bigTrades.Subscribe(t => Console.WriteLine($"{t.Symbol}: opera con volumen {t.Volume}"));
Las dos características clave de Rx son:
una forma claramente definida de representar y manejar secuencias de datos en vivo ( IObservable<T>
)
un conjunto de operadores (como el operador Where
que se acaba de mostrar) que permite expresar la lógica de procesamiento de eventos de forma declarativa
Rx se ha aplicado con especial éxito en interfaces de usuario. (Esto también es cierto fuera de .NET: RxJS es un derivado de JavaScript de Rx y es muy popular en el código de la interfaz de usuario). https://github.com/reactiveui/reactiveui hace un uso profundo de Rx para admitir Desarrollo de interfaz de usuario .NET.
Ian Griffiths presentó una descripción general concisa de 60 minutos de Reactive Extensions para .NET en la reunión de dotnetsheff en 2020. Hay más videos disponibles en la lista de reproducción de Rx.
Aunque Rx es una forma natural de modelar procesos asincrónicos, su diseño original suponía que el código que actúa sobre las notificaciones se ejecutaría de forma sincrónica. Esto se debe a que el diseño de Rx es anterior a las características del lenguaje async
/ await
de C#. Entonces, aunque Rx ofrece adaptadores que pueden convertir entre IObservable<T>
y Task<T>
, hubo ciertos casos en los que async
no era una opción.
AsyncRx.Net elimina esta restricción definiendo IAsyncObservable<T>
. Esto permite a los observadores utilizar código asincrónico. Por ejemplo, si bigTrades
fuera un IAsyncObservable<Trade>
podríamos escribir esto:
bigTrades.Subscribe(async t => await bigTradeStore.LogTradeAsync(t));
AsyncRx.Net se encuentra actualmente en versión preliminar.
Rx define todos los operadores LINQ estándar disponibles para otros proveedores, pero también agrega numerosos operadores adicionales. Por ejemplo, define Scan
, que realiza el mismo procesamiento básico que el operador Aggregate
estándar, pero en lugar de producir un único resultado después de procesar cada elemento, produce una secuencia que contiene el valor agregado después de cada paso. (Por ejemplo, si la operación que se agrega es una suma, Aggregate
devolvería la suma total como una única salida, mientras que Scan
produciría un total acumulado para cada entrada. Dada una secuencia [1,2,3]
, Aggregate((a, x) => a + x)
produce solo 6
, mientras que Scan
produciría [1,3,6]
.)
Algunos de los operadores adicionales que define Rx son útiles sólo cuando se trabaja con eventos. Pero algunos son aplicables a secuencias de cualquier tipo. Entonces, las Extensiones interactivas (Ix para abreviar) definen implementaciones para IEnumerable<T>
. Ix es efectivamente una extensión de LINQ to Objects, que agrega numerosos operadores adicionales. (Su utilidad se ve confirmada por el hecho de que las bibliotecas de tiempo de ejecución de .NET, con el tiempo, han agregado algunos de los operadores que solían estar disponibles solo en Ix. Por ejemplo, .NET 6 agregó MinBy
y MaxBy
, operadores que anteriormente solo estaban definidos por Ix.)
Esta biblioteca se llama "Extensiones interactivas" porque "Interactiva" es, en cierto sentido, lo opuesto a "Reactiva". (El nombre no se refiere a las interacciones del usuario).
IAsyncEnumerable
( System.Linq.Async
) Una de las características iniciadas por Ix fue una versión asincrónica de IEnumerable<T>
. Este es otro ejemplo de una característica tan útil que finalmente se agregó a las bibliotecas de tiempo de ejecución de .NET: .NET Core 3.0 introdujo IAsyncEnumerable<T>
y la versión asociada C# (8.0) agregó soporte intrínseco para esta interfaz con su construcción await foreach
.
Aunque .NET Core 3.0 definió IAsyncEnumerable<T>
, no agregó ninguna implementación LINQ correspondiente. Mientras que IEnumerable<T>
admite todos los operadores estándar como Where
, GroupBy
y SelectMany
, .NET no tiene implementaciones integradas de ninguno de estos para IAsyncEnumerable<T>
. Sin embargo, Ix había proporcionado operadores LINQ para su versión prototipo de IAsyncEnumerable<T>
desde el principio, por lo que cuando se lanzó .NET Core 3.0, fue una tarea relativamente sencilla actualizar todos esos operadores LINQ existentes para que funcionaran con el nuevo IAsyncEnumerable<T>
oficial. IAsyncEnumerable<T>
.
Por lo tanto, se creó el paquete NuGet System.Linq.Async, que proporciona una implementación de LINQ to Objects para IAsyncEnumerable<T>
para que coincida con la ya integrada en .NET para IEnumerable<T>
.
Dado que todo el código relevante ya formaba parte del proyecto Ix (con IAsyncEnumerable<T>
también definido originalmente por este proyecto), el paquete System.Linq.Async NuGet se compila como parte del proyecto Ix.
Algunas de las mejores formas de contribuir son probar cosas, registrar errores y participar en conversaciones de diseño.
Clona las fuentes: git clone https://github.com/dotnet/reactive
Construyendo, probando y depurando las fuentes.
Cómo contribuir
Solicitudes de extracción: abiertas/cerradas
¿Buscas algo en lo que trabajar? La lista de temas en juego es un excelente lugar para comenzar.
Este proyecto ha adoptado un código de conducta adaptado del Pacto del Colaborador para aclarar el comportamiento esperado en nuestra comunidad. Este código de conducta ha sido adoptado por muchos otros proyectos. Para más información consulte el Código de conducta.
Este proyecto es parte de .NET Foundation junto con otros proyectos como .NET Runtime. La Fundación .NET proporciona a este proyecto infraestructura DevOps para compilar, probar, firmar y empaquetar esta compleja solución que cuenta con más de 100 millones de descargas. También proporciona una tutela que permite que el proyecto pase de mantenedor a mantenedor, permitiendo la continuidad de la comunidad.
Las personas que actualmente mantienen Rx son:
Ian Griffiths Hove, Reino Unido El blog de Ian en endjin.com | Howard van Rooijen Winchester, Reino Unido El blog de Howard en endjin.com |
Rx existe desde hace aproximadamente una década y media, por lo que le debemos mucho a sus creadores y a las muchas personas que han trabajado en él desde entonces. Consulte AUTHORS.txt para obtener una lista completa.
Como parte de .NET Conf 2023, Ian Griffiths proporcionó una actualización sobre los esfuerzos para modernizar Rx.NET para v6.0 y los planes para v7.0.
Para obtener más información, consulte las siguientes discusiones:
Embalaje futuro de Rx.NET
Plan de alto nivel Rx.NET v6.0 y v7.0
Hemos establecido una hoja de ruta que explica nuestros planes a mediano plazo para el desarrollo continuo de Rx. Este diagrama ilustra nuestra visión de las plataformas en las que se utiliza Rx y los ciclos de vida de soporte planificados para estos diversos objetivos: