Programação Reativa em C# (.NET): Observable, Rx.NET e trabalho com fluxos de dados
Programação Reativa (Reactive Programming) é um paradigma orientado ao processamento assíncrono de fluxos de dados e propagação de mudanças. No ecossistema C# (.NET), este conceito é implementado através da biblioteca Rx.NET (Reactive Extensions) e das interfaces IObservable<T> / IObserver<T>. Diferentemente da abordagem imperativa clássica, a programação reativa permite descrever declarativamente como o sistema deve reagir a eventos, sem bloquear o fluxo principal de execução.
Na página PythonLib, exploraremos os principais componentes da programação reativa em C#, incluindo sequências Observable, operadores LINQ para transformação de fluxos e exemplos práticos de uso.
Conceitos fundamentais da programação reativa em C#
A programação reativa baseia-se no padrão Observer, onde:
- Observable — fonte de dados (fluxo de eventos).
- Observer — assinante que reage aos dados recebidos.
- Subscription — mecanismo de gerenciamento da assinatura (cancelamento da assinatura do fluxo).
No .NET, esses conceitos são representados pelas interfaces IObservable<T> e IObserver<T>, mas na prática é mais comum usar a biblioteca Rx.NET (pacote NuGet System.Reactive), que fornece um rico conjunto de operadores para trabalhar com sequências.
Instalação do Rx.NET
Para começar, adicione o pacote NuGet ao projeto:
Install-Package System.ReactiveOu via .NET CLI:
dotnet add package System.ReactiveCriação de Observable e assinatura em um fluxo de dados
Vamos considerar um exemplo simples: criar um Observable que gera números de 1 a 5 com atraso e assinar ele.
using System;using System.Reactive.Linq;using System.Threading.Tasks;
class Program{ static async Task Main() { // Cria uma sequência Observable var observable = Observable.Interval(TimeSpan.FromSeconds(1)) .Select(x => x + 1) // Começa em 1 .Take(5); // Pega apenas 5 elementos
// Assina o fluxo var subscription = observable.Subscribe( onNext: value => Console.WriteLine($"Recebido: {value}"), onError: error => Console.WriteLine($"Erro: {error.Message}"), onCompleted: () => Console.WriteLine("Fluxo concluído") );
// Aguarda a conclusão (em código real, use await ou bloqueio) await Task.Delay(6000);
// Cancela a assinatura (libera recursos) subscription.Dispose(); }}Operadores LINQ para transformação de fluxos
Uma das principais vantagens do Rx.NET é a capacidade de aplicar operadores familiares do LINQ aos fluxos de dados: Where, Select, Aggregate e outros. Isso permite descrever transformações de forma declarativa.
Exemplo: filtragem e transformação
using System;using System.Reactive.Linq;
var numbers = Observable.Range(1, 10);
var processed = numbers .Where(n => n % 2 == 0) // Apenas pares .Select(n => n * n) // Eleva ao quadrado .Do(n => Console.WriteLine($"Processado: {n}")); // Efeito colateral
processed.Subscribe( onNext: n => Console.WriteLine($"Resultado: {n}"), onCompleted: () => Console.WriteLine("Pronto"));Combinação de múltiplos fluxos
O Rx.NET suporta mesclagem, junção e combinação de fluxos. Por exemplo, Merge combina vários Observable em um:
<
Também na biblioteca
GraphQL em TypeScript: Bibliotecas para APIs com segurança de tipos
Event Bus e padrão Observer em C++: implementação e exemplos
Glide/Coil para Kotlin: guia completo com exemplos
Trabalho com ZIP/arquivos em Swift (iOS/macOS): guia completo