Este repositório contém quatro bibliotecas que estão conceitualmente relacionadas, pois todas se preocupam com o LINQ sobre sequências de coisas:
Extensões reativas para .NET, também conhecidas como Rx.NET ou Rx (System.Reactive): uma biblioteca para programação orientada a eventos com um modelo declarativo combinável
AsyncRx.NET (visualização experimental) (System.Reactive.Async): implementação experimental de Rx para IAsyncObservable<T>
oferecendo suporte async
/ await
mais profundo
Extensões interativas para .NET, também conhecidas como Ix (System.Interactive): operadores LINQ estendidos para IAsyncEnumerable
e IEnumerable
LINQ for IAsyncEnumerable
(System.Linq.Async): implementa operadores LINQ padrão para IAsyncEnumerable
Cada um será descrito posteriormente neste README.
A programação reativa fornece clareza quando nosso código precisa responder a eventos. As bibliotecas Rx.NET foram projetadas para permitir que aplicativos nativos da nuvem processem dados em tempo real de maneira confiável e previsível.
Escrevemos um livro GRATUITO que explica as abstrações vitais que sustentam o Rx e mostra como explorar a poderosa e extensa funcionalidade incorporada nas bibliotecas Rx.NET.
Baseado no livro de Lee Campbell de 2010 (gentilmente doado ao projeto), ele foi reescrito para atualizá-lo com Rx.NET v6.0, .NET 8.0 e casos de uso modernos nativos da nuvem, como IoT e real- processamento de dados de fluxo de tempo.
A introdução ao Rx.NET está disponível online, no GitHub, como PDF e EPUB.
Canal | Rx | AsyncRx | IX | Sistema.Linq.Async |
---|---|---|---|---|
NuGet.org | ||||
Visualização do NuGet.org (se for mais recente que o lançamento) | ||||
Construir | Construído como parte do Ix | |||
Azul Artefatos | ||||
Histórico de lançamento | Histórico de lançamento | Histórico de lançamento | Histórico de lançamento |
Para compilações noturnas, configure o NuGet para usar este feed: https://pkgs.dev.azure.com/dotnet/Rx.NET/_packaging/RxNet/nuget/v3/index.json
Encontre-nos no canal #rxnet em https://reactivex.slack.com/
Nesta era digital, os fluxos de dados ao vivo são onipresentes. As aplicações financeiras dependem de uma resposta rápida a informações oportunas. As redes de computadores sempre foram capazes de fornecer informações abrangentes sobre seu funcionamento e funcionamento. As empresas de serviços públicos, como os fornecedores de água, têm um grande número de dispositivos que monitorizam as suas operações. A interface do usuário e as estruturas de construção de jogos relatam as interações do usuário detalhadamente. As vans de entrega relatam continuamente seu progresso. As aeronaves fornecem telemetria de desempenho para detectar possíveis problemas de manutenção antes que se tornem problemas sérios, e os carros agora estão começando a fazer o mesmo. Muitos de nós usamos ou carregamos dispositivos que monitoram nossa atividade física e até mesmo sinais vitais. E as melhorias no aprendizado de máquina enriqueceram os insights que podem ser derivados do volume e da variedade cada vez maiores de dados em tempo real.
Mas apesar de serem tão difundidos, os fluxos de informação ao vivo sempre foram uma espécie de cidadão de segunda classe. Quase todas as linguagens de programação têm alguma maneira inata de trabalhar com listas de dados (por exemplo, arrays), mas esses mecanismos tendem a presumir que os dados relevantes já estão na memória, prontos para trabalharmos com eles. O que falta é a vivacidade – o facto de uma fonte de informação poder produzir novos dados a qualquer momento, de acordo com o seu próprio calendário.
Rx eleva o suporte para fluxos de informações ao vivo ao mesmo nível que esperamos para coisas como arrays. Aqui está um exemplo:
var bigTrades = de negociação em negociações onde trade.Volume > 1_000_000 selecione negociação;
Isso usa o recurso LINQ do C# para filtrar trades
para entidades com volume superior a um milhão. Esta sintaxe de expressão de consulta é apenas uma abreviação para chamadas de método, então também poderíamos escrevê-la desta forma:
var bigTrades = trades.Where(trade => trade.Volume > 1_000_000);
O comportamento exato desses dois trechos de código (equivalentes) depende do tipo trades
. Se fosse um IEnumerable<Trade>
, essa consulta apenas percorreria a lista e bigTrades
seria uma sequência enumerável contendo apenas os objetos correspondentes. Se trades
fossem um objeto representando uma tabela de banco de dados (por exemplo, um Entity Framework DbSet, isso seria traduzido em uma consulta ao banco de dados. Mas se estivéssemos usando Rx, trades
seriam um IObservable<Trade>
, um objeto que relata eventos ao vivo à medida que ocorrem E bigTrades
também seria um IObservable<Trade>
, relatando apenas aquelas negociações com volume superior a um milhão. Podemos fornecer ao Rx um retorno de chamada a ser invocado sempre que uma fonte observável tiver algo. para nós:
bigTrades.Subscribe(t => Console.WriteLine($"{t.Symbol}: negociação com volume {t.Volume}"));
Os dois principais recursos do Rx são:
uma maneira claramente definida de representar e lidar com sequências de dados ao vivo ( IObservable<T>
)
um conjunto de operadores (como o operador Where
que acabamos de mostrar) permitindo que a lógica de processamento de eventos seja expressa declarativamente
Rx foi aplicado com especial sucesso em interfaces de usuário. (Isso também é verdade fora do .NET – RxJS é um spin-off de JavaScript do Rx e é muito popular no código da interface do usuário.) O https://github.com/reactiveui/reactiveui faz uso profundo do Rx para oferecer suporte Desenvolvimento de interface do usuário .NET.
Ian Griffiths apresentou uma visão geral concisa de 60 minutos das extensões reativas para .NET no encontro dotnetsheff em 2020. Mais vídeos estão disponíveis na lista de reprodução Rx.
Embora Rx seja uma forma natural de modelar processos assíncronos, seu design original presumia que o código que atuava nas notificações seria executado de forma síncrona. Isso ocorre porque o design do Rx é anterior aos recursos de linguagem async
/ await
do C#. Portanto, embora o Rx ofereça adaptadores que podem converter entre IObservable<T>
e Task<T>
, houve certos casos em que async
não era uma opção.
AsyncRx.Net elimina essa restrição definindo IAsyncObservable<T>
. Isso permite que os observadores usem código assíncrono. Por exemplo, se bigTrades
fosse um IAsyncObservable<Trade>
poderíamos escrever isto:
bigTrades.Subscribe(async t => aguarda bigTradeStore.LogTradeAsync(t));
AsyncRx.Net está atualmente em versão prévia.
Rx define todos os operadores LINQ padrão disponíveis para outros provedores, mas também adiciona vários operadores adicionais. Por exemplo, ele define Scan
, que executa o mesmo processamento básico que o operador Aggregate
padrão, mas em vez de produzir um único resultado após processar cada elemento, produz uma sequência contendo o valor agregado após cada etapa. (Por exemplo, se a operação que está sendo agregada for uma adição, Aggregate
retornaria a soma total como uma única saída, enquanto Scan
produziria um total corrente para cada entrada. Dada uma sequência [1,2,3]
, Aggregate((a, x) => a + x)
produz apenas 6
, enquanto Scan
produziria [1,3,6]
.)
Alguns dos operadores adicionais que Rx define são úteis somente quando você está trabalhando com eventos. Mas alguns são aplicáveis a sequências de qualquer tipo. Portanto, as extensões interativas (abreviadamente Ix) definem implementações para IEnumerable<T>
. Ix é efetivamente uma extensão do LINQ to Objects, adicionando vários operadores adicionais. (Sua utilidade é confirmada pelo fato de que as bibliotecas de tempo de execução do .NET adicionaram, ao longo do tempo, alguns dos operadores que costumavam estar disponíveis apenas no Ix. Por exemplo, o .NET 6 adicionou MinBy
e MaxBy
, operadores anteriormente definidos apenas por Ix.)
Esta biblioteca é chamada de "Extensões Interativas" porque "Interativa" é, em certo sentido, o oposto de "Reativa". (O nome não se refere às interações do usuário.)
IAsyncEnumerable
( System.Linq.Async
) Um dos recursos pioneiros de Ix foi uma versão assíncrona de IEnumerable<T>
. Este é outro exemplo de um recurso tão útil que acabou sendo adicionado às bibliotecas de tempo de execução do .NET: o .NET Core 3.0 introduziu IAsyncEnumerable<T>
e a versão associada C# (8.0) adicionou suporte intrínseco para esta interface com sua construção await foreach
.
Embora o .NET Core 3.0 tenha definido IAsyncEnumerable<T>
, ele não adicionou nenhuma implementação LINQ correspondente. Considerando que IEnumerable<T>
oferece suporte a todos os operadores padrão, como Where
, GroupBy
e SelectMany
, o .NET não possui implementações internas de nenhum deles para IAsyncEnumerable<T>
. No entanto, Ix forneceu operadores LINQ para sua versão protótipo de IAsyncEnumerable<T>
desde o início, portanto, quando o .NET Core 3.0 foi lançado, foi uma tarefa relativamente simples atualizar todos os operadores LINQ existentes para trabalhar com o novo IAsyncEnumerable<T>
oficial. IAsyncEnumerable<T>
.
Assim, o pacote System.Linq.Async NuGet foi criado, fornecendo uma implementação de LINQ to Objects para IAsyncEnumerable<T>
para corresponder àquela já incorporada no .NET para IEnumerable<T>
.
Como todo o código relevante já fazia parte do projeto Ix (com IAsyncEnumerable<T>
também originalmente definido por este projeto), o pacote System.Linq.Async NuGet é criado como parte do projeto Ix.
Algumas das melhores maneiras de contribuir são experimentar coisas, registrar bugs e participar de conversas sobre design.
Clone as fontes: git clone https://github.com/dotnet/reactive
Construindo, testando e depurando as fontes
Como contribuir
Solicitações pull: abertas/fechadas
Procurando algo para trabalhar? A lista de questões em aberto é um ótimo lugar para começar.
Este projeto adotou um código de conduta adaptado do Contributor Covenant para esclarecer o comportamento esperado em nossa comunidade. Este código de conduta foi adotado por muitos outros projetos. Para mais informações consulte o Código de Conduta.
Este projeto faz parte da .NET Foundation junto com outros projetos como o .NET Runtime. A .NET Foundation fornece a este projeto infraestrutura DevOps para compilar, testar, assinar e empacotar esta solução complexa que tem mais de 100 milhões de downloads. Também fornece tutela permitindo que o projeto passe de mantenedor para mantenedor, possibilitando continuidade para a comunidade.
As pessoas que atualmente mantêm Rx são:
Ian Griffiths Hove, Reino Unido Blog de Ian em endjin.com | Howard van Rooijen Winchester, Reino Unido Blog de Howard em endjin.com |
O Rx existe há cerca de uma década e meia, por isso devemos muito aos seus criadores e às muitas pessoas que trabalharam nele desde então. Consulte AUTHORS.txt para obter uma lista completa.
Como parte do .NET Conf 2023, Ian Griffiths forneceu uma atualização sobre os esforços para modernizar o Rx.NET para v6.0 e os planos para v7.0.
Para obter mais informações, consulte as seguintes discussões:
Futura embalagem Rx.NET
Plano de alto nível Rx.NET v6.0 e v7.0
Estabelecemos um roteiro explicando nossos planos de médio prazo para o desenvolvimento contínuo do Rx. Este diagrama ilustra nossa visão das plataformas nas quais o Rx é usado e os ciclos de vida de suporte planejados para esses vários alvos: