Async / Await vs Threads

100

In .Net 4.5 hat Microsoft die neue Async/AwaitFunktion hinzugefügt , um die asynchrone Codierung zu vereinfachen. Ich frage mich jedoch

  1. Kann Async/Awaitdie alte Art der Verwendung vollständig ersetzen Threads?
  2. Ist Async/Awaitin der Lage, alles zu tun, was ein Threadasynchron tun kann?
  3. Kann Async/Awaitnur mit einigen Methoden wie verwendet werden WebClient.DownloadStringAsyncoder kann ich eine synchrone Methode konvertieren, um sie zu verwenden Async/Awaitund den Hauptthread nicht zu blockieren?
Roman Ratskey
quelle
2
Threads und Async / Await sind nicht verwandte Funktionen. Sie können sie kombinieren, müssen es aber nicht.
dtb
2
Ich dachte, dass Async / Await dasselbe new Thread(() => {Some Work}).Start();macht wie ?! ist es nicht?
Roman Ratskey
2
Nee. Ihre Annahme ist nicht richtig. Möglicherweise denken Sie an Task.Run (TPL), das häufig mit Async / Await kombiniert wird, aber auch nichts damit zu tun hat und nicht damit verwendet werden muss.
dtb
4
@dtb: Wann sollte Async / Await und wann Threads verwendet werden? Ich bin wirklich verwirrt über den Unterschied zwischen Task.Run, Thread.Start, Async / Await. Wenn Sie mir eine gute Erklärung geben könnten, die mich die Unterschiede zwischen ihnen verstehen lässt, wäre ich sehr dankbar
Roman Ratskey
2
Async / await erstellt keine Threads oder verwendet sie auf andere Weise.
wRAR

Antworten:

78

Kann es die alte Art der Verwendung von Threads vollständig ersetzen?

Nein. Ein Thread kann viele weitere nützliche Dinge tun. Await ist speziell zu behandeln entworfen etwas Zeit nehmen, am typischsten eine E / A - Anforderung. Dies wurde traditionell mit einem Rückruf durchgeführt, als die E / A-Anforderung abgeschlossen war. Das Schreiben von Code, der auf diesen Rückrufen beruht, ist ziemlich schwierig. Das Warten vereinfacht dies erheblich.

fähig zu tun, was auch immer ein Thread asynchron tun kann?

Grob. Await kümmert sich nur um die Verzögerung, sonst macht es nichts, was ein Thread macht. Der Ausdruck " Warten", der rechts neben dem Schlüsselwort "Warten" steht, erledigt die Aufgabe. Im Idealfall wird überhaupt kein Thread verwendet, es wird eine Treiberanforderung gesendet, und sobald der Treiber die Datenübertragung abgeschlossen hat, wird ein Rückruf für die Abschlussbenachrichtigung generiert. Netzwerke sind bei weitem die häufigste Verwendung, Latenzen von Hunderten von Millisekunden sind häufig und ein unvermeidlicher Nebeneffekt von Diensten, die vom Desktop oder LAN in die "Cloud" verlagert werden. Die synchrone Verwendung solcher Dienste würde dazu führen, dass eine Benutzeroberfläche nicht mehr reagiert.

kann nur mit einigen Methoden wie WebClient.DownloadStringAsync verwendet werden

Nein. Sie können es mit jeder Methode verwenden, die eine Aufgabe zurückgibt. Die XxxxAsync () -Methoden sind im .NET Framework nur vorgekochte Methoden für allgemeine Vorgänge, die Zeit benötigen. Wie das Herunterladen von Daten von einem Webserver.

Hans Passant
quelle
4
Was ist im modernen C # -Aspekt der beste Ansatz, um Async-Callbacks auf externen APIs zu erzielen?
BonCodigo
5
Verwenden Sie im letzten Absatz eine Aufgabe.
Hans Passant
Ich würde erwarten, dass ein Thread etwas kann, das nicht über die asynchrone Programmierung als Beispiel möglich ist.
Saeed Neamati
1
Könnten Sie auf "Ein Thread kann noch viele weitere nützliche Dinge tun" erweitern? Es wäre hilfreich, die Funktionen zu verstehen, für die Threads asyncungeeignet sind.
Benjohn
1
Erwähnenswert await Task.Runfür CPU-gebundene Arbeiten. Wenn ich das richtig verstehe, erreicht das manchmal das, was man sonst für einen Thread oder einen Hintergrundarbeiter tun würde.
ToolmakerSteve
15

Die offizielle Erklärung dazu. Sie sollten jedoch die Unterschiede zwischen Threads und asynchroner Programmierung verstehen, bevor Sie blind eines durch andere ersetzen.

wRAR
quelle
Dies ist wie die erste Ressource, die ich über Threads und Async / Await gelesen habe und die klar und prägnant ist.
Arman Bimatov
2
Diese Antwort enthält nur einen Link zur Dokumentation. Da der Link möglicherweise veraltet ist, ist die Antwort möglicherweise auch veraltet - oder noch schlimmer - völlig nutzlos. Wir empfehlen Benutzern von Stack, die relevanten Teile der Links stattdessen direkt in ihre Frage zu posten.
HimBromBeere
1
Leider erklärt die offizielle Erklärung nicht, wann dies zu tun ist await Task.Run. Es gibt eine kurze Erwähnung von Task.Run, aber es ist nicht klar. Fazit ist, dass awaiteine CPU-gebundene Aufgabe für sich genommen nicht parallel ausgeführt wird, daher sollten solche Arbeiten über ausgeführt werden await Task.Run.
ToolmakerSteve
1

Ich denke so darüber nach (und Microsoft auch, wenn Sie sich https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 ansehen) ) #threads )

Async / await ist eine schnelle Möglichkeit, Code auf dem Hauptanwendungsthread auszuführen, mit dem Vorteil, dass sich der Code selbst aussetzen kann, wenn keine Arbeit zu erledigen ist, und den Fokus auf den Hauptthread zurückgibt und dort auf dem Hauptthread "aufwacht" ist ein Ergebnis, das erhalten werden muss, und leitet die Verarbeitung dann - Sie haben es erraten - an den Haupt-Thread zurück. Stellen Sie sich das wie eine ereignisbasierte GOTO-Anweisung in Basic vor, die die Steuerung an eine bestimmte Ausführungszeile weitergeben kann.

Im Gegensatz dazu ist ein Thread ein separater Ausführungsstrom, der mit eigenen Variablen usw. ausgeführt werden kann, wobei bei ausreichender Hardware die Ausführung parallel zum Hauptthread erfolgt.

Wenn Sie eine GUI-Anwendung haben, die eine einzelne Datei herunterladen und dann beim Herunterladen etwas mit dieser Datei tun wird, würde ich dies mithilfe einer asynchronen / wartenden Methode implementieren.

Wenn Ihre GUI jedoch 5000 Dateien herunterladen muss, würde ich einen Datei-Download-Thread erstellen, um dies zu handhaben, da der Haupt-GUI-Thread möglicherweise einfriert, während die Ausführung übertragen wird, um das Herunterladen der Dateien zu handhaben.

xflowXen
quelle