Können asynchrone Methoden vor dem ersten "Warten" teuren Code enthalten?

8
___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ tag123net ___ Das .NET-Framework ist ein Software-Framework, das hauptsächlich für das Microsoft Windows-Betriebssystem entwickelt wurde. Es enthält eine Implementierung der Basisklassenbibliothek, Common Language Runtime (allgemein als CLR bezeichnet), Common Type System (allgemein als CTS bezeichnet) und Dynamic Language Runtime. Es unterstützt viele Programmiersprachen, einschließlich C #, VB.NET, F # und C ++ / CLI. NICHT für Fragen zu .NET Core verwenden. ___ tag123taskparallellibrary ___ Die Task Parallel Library ist Teil von .NET 4 und .NET 4.5. Es ist eine Reihe von APIs, mit denen Entwickler asynchrone Anwendungen programmieren können. ___ qstnhdr ___ Können asynchrone Methoden vor dem ersten "Warten" teuren Code enthalten? ___ tag123asyncctp ___ Dies umfasst das asynchrone Programmiermodell, das von verschiedenen Programmiersprachen unterstützt wird, unter Verwendung der Schlüsselwörter async und await. ___ answer8449192 ___

Wie Reed sagt, kommt es wirklich auf den Kontext an. Der Code muss unter einige -Punkte laufen - aber abhängig vom Kontext wird er möglicherweise in einem Thread-Pool-Thread ausgeführt, anstatt in einem kritischen Thread.

Anstatt await zu verwenden, verwende ich TaskEx.Run :

%Vor%

Soweit ich weiß, ist das im Prinzip eine Möglichkeit, sofort zum Aufrufer zurückzukehren, aber den Rest der asynchronen Methode sofort zu planen. Wenn Sie beispielsweise einen Windows Forms-Benutzeroberflächen-Thread verwenden, ist dies sinnlos, da Sie sofort zum Benutzeroberflächenthread zurückkehren (und dort teuren Code ausführen) - aber es wäre sinnvoll, wenn Sie sich in einem Kontext befinden wo der aktuelle Thread nicht blockiert werden sollte, aber Fortsetzungen auf einem anderen Thread ausgeführt werden.

    
___ answer8449145 ___

Es ist nicht unbedingt schlecht, aber es kann unerwartete Folgen haben. Wenn der Aufrufer erwartet, dass sich der Code vollständig asynchron verhält, wird der teure Code synchron ausgeführt. Dies wird dazu führen, dass es sich teilweise wie eine synchrone Methode verhält, aber auch asynchron, was die schlimmste der beiden Welten ist (zusätzliche Komplexität von Asynchronität ohne Repressivität ...)

Wenn möglich, würde ich empfehlen, so wenig "teuren" Code zu haben, der zum ersten Warten führt. Die Verwendung von %code% (oder %code% im CTP) zum Umpacken des teuren Codes oder das Verschieben des teuren Codes in eine eigene asynchrone Methode (auf die Sie %code% anwenden könnten) wäre in diesem Fall von Vorteil.

    
___
Lawrence Wagerfield 09.12.2011, 17:09
quelle

2 Antworten

10

Wie Reed sagt, kommt es wirklich auf den Kontext an. Der Code muss unter einige -Punkte laufen - aber abhängig vom Kontext wird er möglicherweise in einem Thread-Pool-Thread ausgeführt, anstatt in einem kritischen Thread.

Anstatt Task.Run zu verwenden, verwende ich TaskEx.Yield :

%Vor%

Soweit ich weiß, ist das im Prinzip eine Möglichkeit, sofort zum Aufrufer zurückzukehren, aber den Rest der asynchronen Methode sofort zu planen. Wenn Sie beispielsweise einen Windows Forms-Benutzeroberflächen-Thread verwenden, ist dies sinnlos, da Sie sofort zum Benutzeroberflächenthread zurückkehren (und dort teuren Code ausführen) - aber es wäre sinnvoll, wenn Sie sich in einem Kontext befinden wo der aktuelle Thread nicht blockiert werden sollte, aber Fortsetzungen auf einem anderen Thread ausgeführt werden.

    
Jon Skeet 09.12.2011, 17:15
quelle
5

Es ist nicht unbedingt schlecht, aber es kann unerwartete Folgen haben. Wenn der Aufrufer erwartet, dass sich der Code vollständig asynchron verhält, wird der teure Code synchron ausgeführt. Dies wird dazu führen, dass es sich teilweise wie eine synchrone Methode verhält, aber auch asynchron, was die schlimmste der beiden Welten ist (zusätzliche Komplexität von Asynchronität ohne Repressivität ...)

Wenn möglich, würde ich empfehlen, so wenig "teuren" Code zu haben, der zum ersten Warten führt. Die Verwendung von Task.Run (oder TaskEx.Run im CTP) zum Umpacken des teuren Codes oder das Verschieben des teuren Codes in eine eigene asynchrone Methode (auf die Sie await anwenden könnten) wäre in diesem Fall von Vorteil.

    
Reed Copsey 09.12.2011 17:11
quelle