In den letzten Tagen habe ich die neuen Funktionen von .net 4.5 und c # 5 getestet.
Ich mag die neuen Async / Wait-Funktionen. Früher hatte ich BackgroundWorker verwendet , um längere Prozesse im Hintergrund mit reaktionsschneller Benutzeroberfläche zu verarbeiten.
Meine Frage ist: Nach diesen netten neuen Funktionen, wann sollte ich async / await verwenden und wann ein BackgroundWorker ? Welches sind die gemeinsamen Szenarien für beide?
Antworten:
async / await soll Konstrukte wie das ersetzen
BackgroundWorker
. Sie können es sicherlich verwenden, wenn Sie möchten, aber Sie sollten in der Lage sein, async / await zusammen mit einigen anderen TPL-Tools zu verwenden, um alles zu handhaben, was da draußen ist.Da beide funktionieren, kommt es auf die persönlichen Vorlieben an, welche Sie wann verwenden. Was geht für Sie schneller ? Was ist für Sie leichter zu verstehen?
quelle
async
/await
auch asynchrone Programmierung ohne Thread-Pool-Threads ermöglicht.Dies ist wahrscheinlich TL; DR für viele, aber ich denke, das Vergleichen
await
mitBackgroundWorker
ist wie das Vergleichen von Äpfeln und Orangen, und meine Gedanken dazu folgen:BackgroundWorker
soll eine einzelne Aufgabe modellieren, die Sie im Hintergrund in einem Thread-Pool-Thread ausführen möchten.async
/await
ist eine Syntax für das asynchrone Warten auf asynchrone Operationen. Diese Operationen können einen Thread-Pool-Thread oder sogar einen anderen Thread verwenden oder nicht . Sie sind also Äpfel und Orangen.Sie können beispielsweise Folgendes tun mit
await
:Aber Sie würden wahrscheinlich nie modellieren, dass Sie in einem Hintergrund-Worker wahrscheinlich so etwas in .NET 4.0 (vorher
await
) tun würden :Beachten Sie die Disjunktheit der Entsorgung im Vergleich zwischen den beiden Syntaxen und wie Sie
using
ohneasync
/ nicht verwenden könnenawait
.Aber so etwas würden Sie nicht machen
BackgroundWorker
.BackgroundWorker
dient normalerweise zum Modellieren einer einzelnen Operation mit langer Laufzeit, die die Reaktionsfähigkeit der Benutzeroberfläche nicht beeinträchtigen soll. Beispielsweise:Es gibt wirklich nichts, mit dem Sie async / await verwenden können. Es
BackgroundWorker
erstellt den Thread für Sie.Jetzt können Sie stattdessen TPL verwenden:
In diesem Fall
TaskScheduler
erstellt der Thread den Thread für Sie (unter der Annahme der StandardeinstellungTaskScheduler
) und kannawait
wie folgt verwendet werden:Meiner Meinung nach ist ein wichtiger Vergleich, ob Sie Fortschritte melden oder nicht. Zum Beispiel könnten Sie Folgendes haben
BackgroundWorker like
:Aber Sie würden sich nicht mit etwas davon befassen, weil Sie die Hintergrund-Worker-Komponente auf die Entwurfsoberfläche eines Formulars ziehen und dort ablegen würden - etwas, das Sie mit
async
/await
undTask
... nicht tun können, dh Sie haben gewonnen. ' t Erstellen Sie das Objekt manuell, legen Sie die Eigenschaften und die Ereignishandler fest. Sie würden nur in dem Körper der füllenDoWork
,RunWorkerCompleted
undProgressChanged
Event - Handler.Wenn Sie das in async / await "konvertieren" würden, würden Sie etwas tun wie:
Ohne die Möglichkeit, eine Komponente auf eine Designer-Oberfläche zu ziehen, muss der Leser wirklich entscheiden, welche "besser" ist. Aber das ist für mich der Vergleich zwischen
await
undBackgroundWorker
nicht, ob Sie auf eingebaute Methoden wie warten könnenStream.ReadAsync
. Wenn Sie beispielsweiseBackgroundWorker
wie vorgesehen verwenden, kann es schwierig sein, die Konvertierung in die Verwendung zu konvertierenawait
.Andere Gedanken: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html
quelle
var t1 = webReq.GetResponseAsync(); var t2 = webReq2.GetResponseAsync(); await t1; await t2;
. Welches würde zwei parallele Operationen warten. Warten ist viel besser für asynchrone, aber sequentielle Aufgaben, IMO ...await Task.WhenAny(t1, t2)
auch etwas tun, wenn eine der beiden Aufgaben zuerst abgeschlossen wurde. Sie möchten wahrscheinlich eine Schleife, um sicherzustellen, dass auch die andere Aufgabe abgeschlossen ist. Normalerweise möchten Sie wissen, wann eine bestimmte Aufgabe abgeschlossen ist, was dazu führt, dass Sie sequentielleawait
s schreiben .Dies ist eine gute Einführung: http://msdn.microsoft.com/en-us/library/hh191443.aspx Der Abschnitt Threads ist genau das, wonach Sie suchen:
quelle
BackgroundWorker wird in .NET 4.5 ausdrücklich als veraltet gekennzeichnet:
Der MSDN-Artikel "Asynchrone Programmierung mit Async und Await (C # und Visual Basic)" lautet :
AKTUALISIEREN
"Für IO-gebundene Operationen, weil der Code einfacher ist und Sie sich nicht vor Rennbedingungen schützen müssen" Welche Rennbedingungen können auftreten, können Sie ein Beispiel geben? ""
Diese Frage hätte als separater Beitrag gestellt werden sollen.
Wikipedia hat eine gute Erklärung für Rennbedingungen. Der notwendige Teil davon ist Multithreading und aus demselben MSDN-Artikel Asynchrone Programmierung mit Async und Await (C # und Visual Basic) :
Das heißt: "Die Schlüsselwörter asynchron und warten führen nicht dazu, dass zusätzliche Threads erstellt werden."
Soweit ich mich an meine eigenen Versuche erinnern kann, als ich diesen Artikel vor einem Jahr studierte, könnten Sie, wenn Sie ein Codebeispiel aus demselben Artikel ausgeführt und damit gespielt haben, auf die Situation stoßen, dass es sich um nicht asynchrone Versionen handelt (Sie könnten versuchen, sie zu konvertieren es für dich) auf unbestimmte Zeit blockieren!
Für konkrete Beispiele können Sie auch diese Site durchsuchen. Hier einige Beispiele:
quelle