Frage

Ich habe Eric Lipperts Blog -Beiträge über Asynchronität in C# 5 gelesen (Teil 4 Besonders relevant zu sein) und haben Anders PDC10 zu diesem Thema gesprochen, und ich bin unklar, wie die Kontinuationen aus asynchronen Methoden in einem einzigen Thread -Kontext wieder aufgenommen werden.

Beide Quellen diskutieren mithilfe von asynchronen Methoden in einer einzelnen Thread -UI -Schleife, um die Reaktionsfähigkeit zu verbessern, und im Beispiel von Anders erwähnt er, dass wenn eine asynchrone Aufgabe abgeschlossen ist, durch die Hinzufügung einer Nachricht an die Nachrichtenpumpe geplant wird.

Weiß die asynchrone Methode wirklich, dass sie eine scheinbar kontextspezifische Aktion ausführen muss, oder war dies eine Vereinfachung?

Wie kann der Wiederaufnahme von asynchronen Methoden im Allgemeinen in einem einzigen Fadenkontext gehandhabt? Gibt es eine Voraussetzung für die Planung innerhalb eines einzelnen Threads?

War es hilfreich?

Lösung

Die Aufgabe -Fortsetzung weiß, wo die Fortsetzung geplant werden muss - zB "Jeder Thread -Pool -Thread" oder "der UI -Thread".

Dieses Verhalten wird jedoch durch den "wartenden" bestimmt - es ist nicht wirklich Teil dessen, wofür der C# Compiler verantwortlich ist. Der Compiler ruft nur an BeginAwait und geht in der Fortsetzung weiter; Der aufmerksame BOOLEAN -Wert gibt an, der angibt, ob die Aufgabe bereits synchron abgeschlossen ist oder ob der Anrufer zurückkehren und die Fortsetzung asynchron auftreten sollte.

Also im Moment wird diese Entscheidung in der erwarteten zurückgegebenen Entscheidung getroffen TaskEx - Aber ich wäre nicht überrascht zu sehen, dass alles gebündelt wird Task letztlich. Das kann Dinge wie den Synchronisationskontext fließen, der weiß, wie weitere Aktionen behandelt werden sollten.

Ich bin mir nicht ganz sicher, was für eine Art original Sie denken über ein Thread-Kontext ... oder denken Sie an eine Situation, in der der Großteil der Arbeit in einem einzelnen Thread stattfinden muss, aber andere Threads können für das asynchrone Bit beteiligt sein (z. B. wenn ein HTTP-Paket empfangen wird , verarbeitet auf einem IO -Abschluss -Port -Thread und der Antwort abgewickelt Zurück auf dem UI -Thread)?

Andere Tipps

Jons Antwort ist natürlich großartig; Ich dachte, ich würde einfach noch etwas hinzufügen.

Betrachten Sie eine WinForms -Anwendung mit einer einzelnen Taste auf einem Formular, in dem Code ausgeführt wird, wenn Sie auf die Schaltfläche klicken.

Was passiert, wenn Sie sind? nicht Klicken Sie auf die Schaltfläche? Nichts. Der Prozess existiert, der Code läuft, aber er scheint nichts zu tun. In der Tat ist es, Nachrichten auf dem UI -Thread zu verarbeiten und festzustellen, dass keiner von ihnen interessant ist, aber es sieht nicht so aus, als würde es etwas Interessantes tun.

Wenn Sie auf die Schaltfläche klicken, ist plötzlich eine dieser Nachrichten interessant, und die Meldungspumpe weiß, dass es beim Klicken auf einen Code ausgeführt werden sollte, wenn sie an Klickereignissen sieht. Also tut es das.

Das Asynchrony-on-a-Single-Thread-Szenario ist genauso. Die Fortsetzung - der Code "Was zu tun nach dem Aufgabe ist" ist effektiv ein "Ereignishandler" des Ereignisses "Aufgabe ist abgeschlossen". Wenn die Aufgabe fertig ist, wird "die Taste gedrückt" und eine Nachricht in die Meldungswarteschlange des UI -Threads enthält. Es spielt keine Rolle, ob es aus dem UI -Thread oder aus einem E/A -Abschluss -Thread oder was auch immer geschieht. Wenn der UI -Thread zur Verarbeitung dieser Nachricht geht, ruft er die Fortsetzung auf. Genauso wie wenn der UI -Thread zur Verarbeitung einer Schaltfläche klickt, ruft er den Klick -Handler auf.

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