TPL vs Reaktive Framework
Als würde man verwenden, wählen Sie Rx über TPL oder sind die 2 Rahmenbedingungen orthogonal?
Was ich verstehen Rx ist hauptsächlich vorgesehen, um eine Abstraktion über die Ereignisse und ermöglichen die Komposition, sondern es ermöglicht auch die Bereitstellung einer Abstraktion, die über asynchrone Operationen.
mit der Createxx überlastungen und die Fromxxx überlastungen und Rücktritt über die Entsorgung der IDisposable zurückgegeben.
TPL bietet auch eine Abstraktion für Vorgänge über Aufgabe und Stornierung Fähigkeiten.
Mein dilemma ist, Wann welcher zu benutzen ist und für welche Szenarien?
- link zu älteren, geschlossenen, doppelten Frage: stackoverflow.com/questions/2138361/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Hauptzweck der Rx ist nicht eine Abstraktion, über die Ereignisse. Dies ist nur eines der Ergebnisse. Seine primäre Ziel ist es, eine composable push-Modell für Sammlungen.
Das reaktive framework (Rx) basiert auf
IObservable<T>
wird die mathematische dualIEnumerable<T>
. Also anstatt "pull" - Elemente aus einer Sammlung mitIEnumerable<T>
haben, können wir Objekte "geschoben", um uns überIObservable<T>
.Natürlich, wenn wir tatsächlich auf die Suche nach beobachtbaren Quellen Dinge wie events & asynchrone Operationen sind ausgezeichnete Kandidaten.
Das reaktive framework erfordert natürlich einen multi-threaded-Modell in der Lage sein, zu beobachten, die Quellen der beobachtbaren Daten und zum verwalten von Anfragen und Abonnements. Rx eigentlich macht starken Gebrauch von der TPL zu tun.
Wenn Sie also Rx Sie sind implizit mit der TPL.
Verwenden Sie den TPL direkt, wenn Sie wollen direkte Kontrolle über Ihre Aufgaben.
Aber wenn du die Quellen der Daten, die Sie beobachten möchten, und führen Sie Abfragen aus gegen dann habe ich durchaus empfehlen das reaktive framework.
Einige Richtlinien, die ich mag, zu Folgen:
Ich mag Scott W ' s bullet-points. Um etwas mehr konkrete Beispiele in
Rx-maps sehr schön zu
TPL scheint die Karte gut zu
Eine Sache, die ich bemerkt haben, mit IObservable (Rx) ist, dass es immer allgegenwärtig. Einmal in Ihrem code-Basis, so wird es ohne Zweifel ausgesetzt sein, die über andere Schnittstellen, es wird schließlich erscheinen alle über Ihre Bewerbung. Ich denke, das kann beängstigend auf den ersten, aber die meisten des Teams ist ziemlich komfortabel mit Rx jetzt und Liebe die Menge der Arbeit, die Sie erspart uns.
IMHO Rx wird der dominante-Bibliothek über die TPL als es schon unterstützt wird .NET 3.5, 4.0, Silverlight 3, Silverlight 4 und Javascript. Dies bedeutet, dass Sie effektiv lernen einen Stil, und es ist für viele Plattformen.
BEARBEITEN: ich habe meine Meinung geändert über Rx wird dominant über TPL. Sie lösen verschiedene Probleme, so sollte nicht wirklich verglichen werden mögen. Mit .NET 4.5/C# 5.0 das async/await-Schlüsselwörter weiter binden uns an die TPL (das ist gut). Für eine Tiefe discuson auf Rx-vs-Veranstaltungen vs TPL etc. überprüfen Sie heraus die erstes Kapitel von meinem online-Buch IntroToRx.com
Update, Dezember 2016:, Wenn Sie über 30 Minuten, empfehle ich Ihnen die Lektüre von Joe Duffy ist aus Erster hand und nicht in meiner Spekulation. Ich denke, dass meine Analyse hält sich gut, aber wenn Sie gefunden haben, diese Frage empfehle ich Ihnen zu sehen, die blog-post, statt diese Antworten, weil neben TPL vs Rx.NET er umfasst auch MS-Forschung-Projekte (Midori, Kosmos).
http://joeduffyblog.com/2016/11/30/15-years-of-concurrency/
Ich denke, dass MS einen großen Fehler gemacht über-die Korrektur nach .NET 2.0 kam heraus. Sie führten viele verschiedene concurrency-management-APIs, die alle zur gleichen Zeit aus verschiedenen teilen des Unternehmens.
Future<T>
und verwandelte sich inTask<T>
)In der Zwischenzeit viele managed API-teams wurden versuchen, Leben mit APM und
Threadpool.QueueUserWorkItem()
, nicht wissend, ob Toub gewinnen würde seinen Kampf SchiffFuture<T>
/Task<T>
im mscorlib.dll. Am Ende sieht es aus wie Sie abgesichert sind, und versendet beideTask<T>
undIObservable<T>
im mscorlib, aber nicht zulassen, dass andere Rx-APIs (auch nichtISubject<T>
) in "mscorlib". Ich denke, dass diese Hecke endete verursacht eine riesige Menge von Vervielfältigung (dazu später mehr) und sich der Aufwand innerhalb und außerhalb des Unternehmens.Zur Vervielfältigung siehe:
Task
vs.IObservable<Unit>
,Task<T>
vs.AsyncSubject<T>
,Task.Run()
vs.Observable.Start()
. Und das ist nur die Spitze des Eisbergs. Aber auf einer höheren Ebene betrachten:IEnumerable
-Stil Verlängerung Methoden, was bedeutet, dass Sie sehr leicht immer blockieren (AnrufeFirst()
auf einem heißen Bach kehrt nie zurück). Scheduling-limits (Begrenzung der Parallelität) erfolgt über seltsameSubscribeOn()
Erweiterung-Methoden, die sind unheimlich implizite und schwer zu bekommen Recht. Wenn Sie beginnen zu lernen, Rx reserve eine lange Zeit zu lernen, all die Fallstricke zu vermeiden. Aber der Rx ist wirklich die einzige option, wenn die Erstellung komplexer ereignisströme oder benötigen Sie komplexe Filter/Abfragen.Ich glaube nicht, dass der Rx hat eine chance auf Breite Akzeptanz, bis MS Schiffe
ISubject<T>
im "mscorlib". Das ist schade, denn Rx enthält einige sehr nützliche Beton (generisch) - Typen, wieTimeInterval<T>
undTimestamped<T>
, die ich denke, sollte in der Core/mscorlib wieNullable<T>
. AuchSystem.Reactive.EventPattern<TEventArgs>
.Ich würde sagen, dass TPL Dataflow umfasst spezielle Teilmenge der Funktionalität in Rx. Datenfluss ist für die Verarbeitung von Daten, die messbare Menge an Zeit, während der Rx ist für Veranstaltungen, wie z.B. Maus-position, Fehlerzustände, etc., wo das handling zu vernachlässigen.
Beispiel: Ihr "abonnieren" - handler asynchron ist und Sie wollen nicht mehr als 1 Vollstrecker an der Zeit. Mit Rx müssen Sie zu blockieren, es gibt keinen anderen Weg um ihn herum, denn Rx ist async-agnostisch und nicht bedrohlich async in besonderer Weise an vielen stellen.
Wenn Sie nicht blockieren, dann Rx berücksichtigen, dass die Aktion abgeschlossen ist, während die hf noch immer asynchron ausgeführt.
Denken Sie vielleicht, wenn Sie
als problem ist gelöst. Aber das wird Ihre Pause .Vollständige() workflow, da Rx wird denken, dass es fertig ist, sobald es Zeitplan der Ausführung und schließen Sie Ihre Anwendung ohne warten auf asynchrone Vorgänge abgeschlossen sind.
Wenn Sie zulassen möchten, dass nicht mehr als 4 gleichzeitige asynchrone Aufgaben als Rx nicht alles bieten out of the box. Vielleicht können Sie hack etwas durch die Umsetzung Ihrer eigenen scheduler, buffer, etc.
TPL Dataflow bieten eine sehr schöne Lösung in ActionBlock. Es kann Gas gleichzeitige Aktionen auf bestimmte Anzahl und es nicht verstehen async-Operationen, also Aufruf von Complete() und warten darauf, dass Abgeschlossen wird genau das tun, was Sie erwarten würde: warten für alle in-progress-asynchrone Aufgaben zu vollenden.
Weiteres feature TPL hat ist der "Gegendruck". Lassen Sie uns sagen, Sie entdeckte einen Fehler in Ihrem Umgang mit routine und müssen die Route neu letzten Monat Daten. Wenn Sie abonnieren, um Ihre Quelle mit Rx, und Ihre pipeline enthält unbegrenzten Puffer, oder ObserveOn, als Sie run out of memory in wenigen Sekunden, da die Quelle Lesen Sie weiter und schneller als die Verarbeitung verarbeitet werden kann. Auch wenn Sie implementieren die Blockierung der Verbraucher, die Quelle leiden kann blockieren Anrufe, zum Beispiel wenn die Quelle ist asynchron. In der TPL, die Sie implementieren können, die Quelle als
welche nicht sperren Quelle warten, während der hf ist überlastet.
Insgesamt fand ich, dass die Rx ist eine gute Passform für die Aktionen, die Zeit und rechnerisch Licht. Wenn die Bearbeitungszeit wird beträchtlich, Sie sind in der Welt der seltsamen Nebenwirkungen und esoterischen Debuggen.
Gute Nachricht ist, dass TPL Dataflow-Blöcke spielen sehr schön mit Rx -. Sie haben AsObserver/AsObservable Adapter und Sie können kleben Sie Sie in der Mitte der Rx-pipeline, wenn nötig. Aber der Rx hat noch viel mehr Muster und Anwendungsfälle. Also meine Faustregel ist, um zu starten mit Rx und add TPL Dataflow, wie gebraucht.