Dieses Repository enthält vier Bibliotheken, die konzeptionell insofern verwandt sind, als sie sich alle mit LINQ über Sequenzen von Dingen befassen:
Reaktive Erweiterungen für .NET, auch bekannt als Rx.NET oder Rx (System.Reactive): eine Bibliothek für ereignisgesteuerte Programmierung mit einem zusammensetzbaren, deklarativen Modell
AsyncRx.NET (experimentelle Vorschau) (System.Reactive.Async): experimentelle Implementierung von Rx für IAsyncObservable<T>
mit tieferer async
/ await
-Unterstützung
Interaktive Erweiterungen für .NET, auch bekannt als Ix (System.Interactive): erweiterte LINQ-Operatoren für IAsyncEnumerable
und IEnumerable
LINQ für IAsyncEnumerable
(System.Linq.Async): implementiert Standard-LINQ-Operatoren für IAsyncEnumerable
Jedes wird später in dieser README-Datei beschrieben.
Reaktive Programmierung sorgt für Klarheit, wann unser Code auf Ereignisse reagieren muss. Die Rx.NET-Bibliotheken wurden entwickelt, um cloudnativen Anwendungen die zuverlässige und vorhersehbare Verarbeitung von Live-Daten zu ermöglichen.
Wir haben ein KOSTENLOSES Buch geschrieben, das die wichtigen Abstraktionen erklärt, die Rx zugrunde liegen, und zeigt, wie man die leistungsstarke und umfangreiche Funktionalität der Rx.NET-Bibliotheken nutzt.
Basierend auf dem Buch von Lee Campbell aus dem Jahr 2010 (das dem Projekt freundlicherweise gespendet wurde) wurde es neu geschrieben, um es mit Rx.NET v6.0, .NET 8.0 und modernen Cloud-nativen Anwendungsfällen wie IoT und realen Anwendungen auf den neuesten Stand zu bringen. Verarbeitung von Zeitstromdaten.
Die Einführung in Rx.NET ist online, auf GitHub, als PDF und EPUB verfügbar.
Kanal | Rx | AsyncRx | Ix | System.Linq.Async |
---|---|---|---|---|
NuGet.org | ||||
NuGet.org-Vorschau (falls neuer als die Version) | ||||
Bauen | Gebaut als Teil von Ix | |||
Azurblau Artefakte | ||||
Veröffentlichungshistorie | Veröffentlichungsverlauf | Veröffentlichungsverlauf | Veröffentlichungsverlauf |
Konfigurieren Sie NuGet für nächtliche Builds für die Verwendung dieses Feeds: https://pkgs.dev.azure.com/dotnet/Rx.NET/_packaging/RxNet/nuget/v3/index.json
Besuchen Sie uns im #rxnet-Kanal unter https://reactivex.slack.com/
Im digitalen Zeitalter sind Live-Datenströme allgegenwärtig. Finanzanträge hängen von einer schnellen Reaktion auf zeitnahe Informationen ab. Computernetzwerke waren schon immer in der Lage, umfassende Informationen über ihren Zustand und ihre Funktionsweise bereitzustellen. Versorgungsunternehmen wie Wasserversorger verfügen über eine Vielzahl von Geräten, die ihren Betrieb überwachen. Benutzeroberflächen- und Game-Building-Frameworks melden Benutzerinteraktionen sehr detailliert. Lieferwagen melden kontinuierlich ihren Fortschritt. Flugzeuge bieten Leistungstelemetrie, um potenzielle Wartungsprobleme zu erkennen, bevor sie zu ernsthaften Problemen werden, und Autos beginnen jetzt, dasselbe zu tun. Viele von uns tragen oder tragen Geräte, die unsere körperliche Aktivität und sogar Vitalfunktionen verfolgen. Und die Verbesserungen beim maschinellen Lernen haben die Erkenntnisse bereichert, die aus der ständig wachsenden Menge und Vielfalt an Live-Daten gewonnen werden können.
Doch trotz ihrer großen Verbreitung waren Live-Informationsströme schon immer so etwas wie Bürger zweiter Klasse. Fast alle Programmiersprachen verfügen über eine angeborene Möglichkeit, mit Datenlisten (z. B. Arrays) zu arbeiten. Diese Mechanismen gehen jedoch tendenziell davon aus, dass sich die relevanten Daten bereits im Speicher befinden und für die Arbeit damit bereitstehen. Was fehlt, ist die Lebendigkeit – die Tatsache, dass eine Informationsquelle jederzeit und nach eigenem Zeitplan neue Daten produzieren kann.
Rx hebt die Unterstützung für Live-Informationsströme auf das gleiche Niveau, wie wir es von Dingen wie Arrays erwarten. Hier ist ein Beispiel:
var bigTrades = from trade in trades where trade.Volume > 1_000_000 select trade;
Dabei wird die LINQ-Funktion von C# verwendet, um trades
auf Entitäten mit einem Volumen von mehr als einer Million herunterzufiltern. Diese Abfrageausdruckssyntax ist nur eine Abkürzung für Methodenaufrufe, wir könnten sie also auch so schreiben:
var bigTrades = trades.Where(trade => trade.Volume > 1_000_000);
Das genaue Verhalten dieser beiden (äquivalenten) Codefragmente hängt davon ab, um welche Art trades
es sich handelt. Wenn es ein IEnumerable<Trade>
wäre, würde diese Abfrage einfach die Liste durchlaufen und bigTrades
wäre eine aufzählbare Sequenz, die nur die passenden Objekte enthält. Wenn trades
ein Objekt wären, das eine Datenbanktabelle darstellt (z. B. ein Entity Framework DbSet), würde dies in eine Datenbankabfrage übersetzt werden. Wenn wir jedoch Rx verwenden, wären trades
ein IObservable<Trade>
, ein Objekt, das Live-Ereignisse so meldet, wie sie es tun Und bigTrades
wäre auch ein IObservable<Trade>
, das nur die Trades mit einem Volumen über einer Million meldet. Wir können Rx einen Rückruf bereitstellen, der jedes Mal aufgerufen wird, wenn eine beobachtbare Quelle vorliegt etwas für uns:
bigTrades.Subscribe(t => Console.WriteLine($"{t.Symbol}: Handel mit Volumen {t.Volume}"));
Die beiden Hauptmerkmale von Rx sind:
eine klar definierte Möglichkeit, Live-Datensequenzen darzustellen und zu verarbeiten ( IObservable<T>
)
eine Reihe von Operatoren (wie der gerade gezeigte Where
Operator), die es ermöglichen, die Logik der Ereignisverarbeitung deklarativ auszudrücken
Rx wurde besonders erfolgreich in Benutzeroberflächen eingesetzt. (Dies gilt auch außerhalb von .NET – RxJS ist ein JavaScript-Ableger von Rx und im Benutzeroberflächencode sehr beliebt.) https://github.com/reactiveui/reactiveui nutzt Rx intensiv zur Unterstützung .NET-UI-Entwicklung.
Ian Griffiths präsentierte beim dotnetsheff-Treffen im Jahr 2020 einen prägnanten 60-minütigen Überblick über Reactive Extensions für .NET. Weitere Videos sind in der Rx-Playlist verfügbar.
Obwohl Rx eine natürliche Methode zur Modellierung asynchroner Prozesse ist, ging sein ursprünglicher Entwurf davon aus, dass Code, der auf Benachrichtigungen reagiert, synchron ausgeführt wird. Dies liegt daran, dass das Design von Rx älter ist als async
/ await
-Sprachfunktionen von C#. Obwohl Rx Adapter anbietet, die zwischen IObservable<T>
und Task<T>
konvertieren können, gab es bestimmte Fälle, in denen async
keine Option war.
AsyncRx.Net hebt diese Einschränkung auf, indem es IAsyncObservable<T>
definiert. Dadurch können Beobachter asynchronen Code verwenden. Wenn bigTrades
beispielsweise ein IAsyncObservable<Trade>
wäre, könnten wir Folgendes schreiben:
bigTrades.Subscribe(async t => waiting bigTradeStore.LogTradeAsync(t));
AsyncRx.Net befindet sich derzeit in der Vorschau.
Rx definiert alle für andere Anbieter verfügbaren Standard-LINQ-Operatoren, fügt aber auch zahlreiche zusätzliche Operatoren hinzu. Es definiert beispielsweise Scan
, das die gleiche grundlegende Verarbeitung durchführt wie der standardmäßige Aggregate
-Operator, aber statt nach der Verarbeitung jedes Elements ein einzelnes Ergebnis zu erzeugen, erzeugt es nach jedem einzelnen Schritt eine Sequenz, die den aggregierten Wert enthält. (Wenn die zu aggregierende Operation beispielsweise eine Addition ist, würde Aggregate
die Gesamtsumme als einzelne Ausgabe zurückgeben, während Scan
eine laufende Summe für jede Eingabe erzeugen würde. Bei einer gegebenen Sequenz [1,2,3]
, Aggregate((a, x) => a + x)
erzeugt nur 6
, während Scan
[1,3,6]
erzeugen würde.)
Einige der zusätzlichen Operatoren, die Rx definiert, sind nur nützlich, wenn Sie mit Ereignissen arbeiten. Einige sind jedoch auf Sequenzen jeglicher Art anwendbar. Die Interactive Extensions (kurz Ix) definieren also Implementierungen für IEnumerable<T>
. Ix ist praktisch eine Erweiterung von LINQ to Objects und fügt zahlreiche zusätzliche Operatoren hinzu. (Seine Nützlichkeit wird durch die Tatsache bestätigt, dass die .NET-Laufzeitbibliotheken im Laufe der Zeit einige der Operatoren hinzugefügt haben, die früher nur in Ix verfügbar waren. Beispielsweise wurden in .NET 6 MinBy
und MaxBy
hinzugefügt, Operatoren, die zuvor nur von definiert wurden Ix.)
Diese Bibliothek wird „Interaktive Erweiterungen“ genannt, weil „Interaktiv“ gewissermaßen das Gegenteil von „Reaktiv“ ist. (Der Name bezieht sich nicht auf Benutzerinteraktionen.)
IAsyncEnumerable
( System.Linq.Async
) Eines der von Ix entwickelten Features war eine asynchrone Version von IEnumerable<T>
. Dies ist ein weiteres Beispiel für eine Funktion, die so nützlich ist, dass sie schließlich zu den .NET-Laufzeitbibliotheken hinzugefügt wurde: .NET Core 3.0 führte IAsyncEnumerable<T>
ein, und die zugehörige Version C# (8.0) fügte mit ihrem Konstrukt await foreach
intrinsische Unterstützung für diese Schnittstelle hinzu .
Obwohl .NET Core 3.0 IAsyncEnumerable<T>
definierte, wurde keine entsprechende LINQ-Implementierung hinzugefügt. Während IEnumerable<T>
alle Standardoperatoren wie Where
, GroupBy
und SelectMany
unterstützt, verfügt .NET über keine integrierten Implementierungen dieser Operatoren für IAsyncEnumerable<T>
. Allerdings hatte Ix von Anfang an LINQ-Operatoren für seine Prototypversion von IAsyncEnumerable<T>
bereitgestellt, sodass es bei der Auslieferung von .NET Core 3.0 eine relativ einfache Aufgabe war, alle vorhandenen LINQ-Operatoren zu aktualisieren, damit sie mit dem neuen, offiziellen IAsyncEnumerable<T>
funktionieren IAsyncEnumerable<T>
.
Daher wurde das System.Linq.Async NuGet-Paket erstellt, das eine LINQ to Objects-Implementierung für IAsyncEnumerable<T>
bereitstellt, die mit der bereits in .NET für IEnumerable<T>
integrierten Version übereinstimmt.
Da der gesamte relevante Code bereits Teil des Ix-Projekts war (wobei IAsyncEnumerable<T>
ursprünglich auch von diesem Projekt definiert wurde), wird das System.Linq.Async NuGet-Paket als Teil des Ix-Projekts erstellt.
Zu den besten Möglichkeiten, einen Beitrag zu leisten, gehören das Ausprobieren, das Melden von Fehlern und die Teilnahme an Designgesprächen.
Klonen Sie die Quellen: git clone https://github.com/dotnet/reactive
Erstellen, Testen und Debuggen der Quellen
So können Sie einen Beitrag leisten
Pull-Anfragen: Offen/Geschlossen
Suchen Sie nach etwas, woran Sie arbeiten können? Die Liste der zu gewinnenden Themen ist ein guter Anfang.
Dieses Projekt hat einen Verhaltenskodex übernommen, der vom Contributor Covenant übernommen wurde, um das erwartete Verhalten in unserer Community zu klären. Dieser Verhaltenskodex wurde von vielen anderen Projekten übernommen. Weitere Informationen finden Sie im Verhaltenskodex.
Dieses Projekt ist zusammen mit anderen Projekten wie der .NET Runtime Teil der .NET Foundation. Die .NET Foundation stellt diesem Projekt eine DevOps-Infrastruktur zur Verfügung, um diese komplexe Lösung mit über 100 Millionen Downloads zu kompilieren, zu testen, zu signieren und zu verpacken. Es bietet auch eine Konservatoriumsfunktion, die es dem Projekt ermöglicht, von Betreuer zu Betreuer zu wechseln und so Kontinuität für die Community zu gewährleisten.
Die Personen, die derzeit Rx pflegen, sind:
Ian Griffiths Hove, Großbritannien Ians Blog auf endjin.com | Howard van Rooijen Winchester, Großbritannien Howards Blog auf endjin.com |
Rx gibt es schon seit etwa anderthalb Jahrzehnten, daher haben wir seinen Schöpfern und den vielen Menschen, die seitdem daran gearbeitet haben, viel zu verdanken. Eine vollständige Liste finden Sie in der Datei AUTHORS.txt.
Im Rahmen der .NET Conf 2023 stellte Ian Griffiths ein Update zu den Bemühungen zur Modernisierung von Rx.NET für v6.0 und den Plänen für v7.0 bereit.
Weitere Informationen finden Sie in den folgenden Diskussionen:
Zukünftige Rx.NET-Verpackung
Rx.NET v6.0 & v7.0 High-Level-Plan
Wir haben eine Roadmap erstellt, die unsere mittelfristigen Pläne für die weitere Entwicklung von Rx erläutert. Dieses Diagramm veranschaulicht unsere Sicht auf die Plattformen, auf denen Rx verwendet wird, und die geplanten Support-Lebenszyklen für diese verschiedenen Ziele: