Frage

In Python die Ausbeute Schlüsselwort kann in beiden Push-und Pull-Kontexten verwendet wird, weiß ich, wie der Pull Kontext in c # zu tun, aber wie würde ich die Push erreichen. Ich poste den Code, den ich aus Python in c # zu replizieren versuchen:

def coroutine(func):
  def start(*args,**kwargs):
    cr = func(*args,**kwargs)
    cr.next()
    return cr
  return start

@coroutine
def grep(pattern):
  print "Looking for %s" % pattern
  try:
    while True:
      line = (yield)
      if pattern in line:
        print line,
  except GeneratorExit:
    print "Going away. Goodbye"
War es hilfreich?

Lösung

Wenn das, was Sie wollen, ist eine „beobachtbaren Sammlung“ -, die eine Sammlung ist, die eher Ergebnisse an Sie schiebt, als sie die Verbraucher ziehen zu lassen - dann wollen Sie wahrscheinlich Blick in die Erweiterungen Reactive Framework. Hier ist ein Artikel über sie:

http://www.infoq.com/news/ 2009/07 / Reactive-Framework LINQ-Event

Nun, wie Sie beachten, können Sie beide „Push“ bauen und „Pull“ style Iteratoren leicht, wenn Sie Koroutinen zur Verfügung haben. (Oder, wie Thomas weist darauf hin, Sie können sie mit Fortsetzungen bauen als auch.) In der aktuellen Version von C # wir nicht wahr Koroutinen (oder Fortsetzungen). Wir sind jedoch sehr besorgt über die Schmerzen Nutzer fühlen sich um asynchrone Programmierung .

Implementieren von faserbasierten Koroutinen als First-Class-Sprache-Funktion ist eine Technik, die möglicherweise verwendet werden könnten, die asynchrone Programmierung einfacher zu machen, aber das ist nur eine mögliche Idee von vielen, die wir derzeit forsch sind. Wenn Sie ein wirklich solides ehrfürchtige Szenario, wo Koroutinen machen einen besseren Job als alles andere - einschließlich der reaktiven Rahmen - dann würde ich gerne mehr darüber hören. Die realistischere Daten, die wir über das, was wirkliche Probleme, die Menschen in der asynchronen Programmierung konfrontiert sind, desto eher sind wir mit einer guten Lösung zu kommen. Dank!

UPDATE: Wir haben vor kurzem angekündigt, dass wir hinzufügen Koroutine artige asynchrone Steuerung fließt in die nächste Version von C # und VB. Sie können es versuchen, dich mit unserer Community Technology Preview Ausgabe, die Sie hier herunterladen .

Andere Tipps

C # nicht über allgemeine Co-Routinen. Eine allgemeine Co-Routine ist, wo die Co-Routine seinen eigenen Stapel hat, das heißt, es andere Methoden aufrufen kann, und diese Methoden können „Ausbeute“ Werte. Umsetzung der allgemeinen Co-Routinen erfordert es einige intelligente Dinge mit Stapeln, möglicherweise bis zu und einschließlich der Zuweisung von Stapelrahmen (die verborgenen Strukturen, die lokale Variablen enthalten) auf der Halde. Dies kann getan werden, einige Sprachen zu tun, dass (z Scheme), aber es ist etwas schwierig, es richtig zu tun. Auch viele Programmierer finden die Funktion schwer zu verstehen.

Allgemeine Co-Routinen können mit Gewinden emuliert werden. Jeder Thread verfügt über einen eigenen Stapel. In einer Co-Routine Setup, beide Threads (der Anfang Anrufer, und der Faden für die Co-Routine) -Steuerung abwechseln, werden sie nicht gleichzeitig in Betrieb tatsächlich. Die „Ausbeute“ Mechanismus ist dann ein Austausch zwischen den beiden Threads, und als solche ist sie teuer (Synchronisation, eine Rundreise durch den OS-Kernel und scheduler ...). Außerdem gibt es viel Raum für Speicherlecks (die Co-Routine explizit werden müssen „gestoppt“, da sonst die Warte Thread bleiben für immer). Somit ist dies selten getan.

C # bietet eine bastardized-down Co-Routine Funktion namens Iteratoren . Der C # Compiler wandelt automatisch den Iterator-Code in einem bestimmten Zustand Klasse, mit lokalen Variablen immer Klassenfelder. Nachgeben wird dann auf der VM-Ebene, eine Ebene return. So etwas ist machbar, solange die „Ausbeute“ von dem Iterator Code selbst durchgeführt wird, nicht von einem Verfahren, welches die Code-Iterator aufruft. C # Iteratoren decken bereits viele Anwendungsfälle und die C # Designer waren nicht bereit, die Straße hinunter, weiter zu gehen, um Fortsetzungen . Einige sarkastisch Leute sind daran interessiert, in dem Zustand, dass die Umsetzung voll funktions Fortsetzungen hat C # so effizient verhindert würde entfernt, als Erzfeind Java (effiziente Fortsetzungen sind machbar, aber dies erfordert einiges an Arbeit mit der GC und dem JIT-Compiler).

Dank @NickLarsen, Sie hat mir geholfen, die neuen Sachen nicht vergessen, dass MS eingeführt haben, die IObservable Schnittstelle.

Link http://msdn.microsoft.com /en-us/library/dd783449(VS.100).aspx

Eigentlich ist .NET nicht „falsche Annahmen“ über Threadaffinität machen, in der Tat abkoppelt es völlig die Vorstellung von einem .NET Level-Thread von dem OS-Ebene Thread.

Was müssen Sie tun, ist eine logische .NET Threadzustand mit Faser assoziieren (für, dass Sie die CLR müssen Hosting-API, aber Sie keinen Host selbst schreiben müssen, können Sie die aus Ihrer eigenen Anwendung benötigt verwenden, um direkt) und alles, Lock-Tracking, Ausnahmebehandlung arbeitet wieder normal.

Ein Beispiel finden Sie hier: http://msdn.microsoft. com / en-us / Magazin / cc164086.aspx

Btw Mono 2.6 enthält geringe Coroutine Unterstützung und verwendet werden kann, alle höhere Ebene Primitiven leicht zu implementieren.

Ich würde gerne eine Faser-basierte API für .NET sehen.

Ich habe versucht, die native Faser API in C # durch p zu verwenden / invoke eine Weile zurück, aber weil die Ausnahmebehandlung der Laufzeit (fälschlicherweise) macht Thread-basierte Annahmen, die Dinge brach (schlecht), wenn Ausnahmen geschehen ist.

Ein „Killer-Applikation“ für einen faserbasierten Koroutine API ist Spiele-Programmierung; bestimmte Arten von AI erfordern einen „leichten“ Thread, dass Sie nach Belieben Zeitscheibe können. Zum Beispiel benötigen Spielverhalten Bäume die Fähigkeit, „Puls“ der Entscheidungscode jedes Bild, so dass der AI-Code kooperativ Ausbeute zurück an den Anrufer, wenn die Entscheidung Scheibe liegt. Dies ist möglich, mit harten Fäden zu implementieren, aber viel, viel komplizierter.

Während also der wahren Faseranwendungsfälle sind nicht Mainstream, es gibt sie auf jeden Fall, und eine kleine Nische von uns .Net Programmierern würde jubeln mit aller Macht, wenn die bestehenden Fehler in dem Faser-Subsystem ausgearbeitet.

Nun, ich gab einen Versuch eine vollständige Bibliothek entwickeln Koroutinen zu verwalten mit nur einem einzigen Thread. Der schwierige Teil war zu nennen Koroutinen innerhalb Koroutinen ... und Parameter zurück, aber schließlich erreichte sie ein ziemlich gutes Ergebnis hier . Die einzige Warnung, daß Blockierung I / O-Operationen müssen über Aufgaben und alll „Rückkehr“ gemacht werden muss mit „yield return“ ersetzt. Mit dem Anwendungsserver auf dieser Bibliothek basiert ich in der Lage war, fast die Anfragen mit einem Standard-Asynchron gemacht zu verdoppeln / await basierend auf IIS. (Suchen Sie für Node.Cs und Node.Cs.Musicstore auf GitHub es zu Hause zu versuchen)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top