async und await
-
Eric Lippert schrieb:
The whole point of "async" methods is to avoid spawning a new thread.
You are confusing asynchrony with concurrency. Asynchronous methods need not run on another thread to be asynchronous. The point of asynchronous methods is that they allow you to break up work into little pieces that need to run in a particular order, but not necessarily without doing other work on the same thread.
Think of a thread as a worker you can hire. Think of a async method as a to-do list with pauses between the items. If your to-do list says "go to the store, buy milk and eggs, go home, make an omelette", then the benefit of async is that when someone calls your cell phone between the "buy eggs" step and the "go home" step and says "can you stop by the pharmacy on your way home and pick up my prescription?" you can take the call and schedule the work before you make the omelette. With non-async methods, your phone keeps ringing until the omelette is done, and then you take the call. The UI blocks until you're done what you're doing.
Your concept is that in order to keep the UI thread responsive, the moment you get the to-do list you go hire some guy to run to the store for you, so that you're free to take the call about the pharmacy. That is expensive and unnecessary. Everything can stay on the same thread with async because the long-running task has built-in points where the UI gets to interrupt and schedule more work.
-
@Helium: Möchtest Du auf was bestimmtes hinaus?
-
theta schrieb:
@Helium: Möchtest Du auf was bestimmtes hinaus?
Mein Wissen über
async
undawait
sind zwar noch nicht so wirklich vollständig, aber bisher habe ich immer gelesen, dassasync
undawait
keine neuen Threads erstellen. Um etwas im Hintergrund auszuführen, muss man dies selbst tun, in dem man zum Beispiel einenTask
erstellt und startet.Womöglich will Helium darauf raus. Und damit auch die Aussage von paulrei korrigieren:
paulrei schrieb:
Naja, in einem Thread kann man ja nix asynchron ausführen...
Doch, man kann etwas asynchron ausführen, obwohl es nur in einem Thread läuft.
Grüssli
-
Dravere schrieb:
Doch, man kann etwas asynchron ausführen, obwohl es nur in einem Thread läuft.
Grüssli
Wuerde mich mal interessieren wie das geht, kann das einer erklaeren? Kann es mir gerade nich vorstellen.
-
Meines Wissens kommen die zusätzlichen Threads vom Thread Pool.
-
Vorab: Ich will hier nicht sagen, dass ich richtig liege. Ich habe es bisher nur so verstanden!
Firefighter schrieb:
Wuerde mich mal interessieren wie das geht, kann das einer erklaeren? Kann es mir gerade nich vorstellen.
Es geht hier ein wenig um die Definition von asynchron. Asynchron heisst "nicht gemeinsam" oder "nicht miteinander". Wenn eine Methode synchron ausgeführt wird, dann wird alles an einem Stück abgearbeitet. Wenn sie asynchron mit dem
async
Schlüsselwort ausgeführt wird, dann wird ein Teil A zuerst und später ein Teil B ausgeführt. A und B können auf dem gleichen Thread laufen, aber werden halt verzögert voneinander ausgeführt.Dabei läuft der UI-Thread, somit der Thread mit einer Nachrichtenschleife, bis zum
await
Aufruf von einenTask
. Der UI Thread hängt nun einen vom Kompiler erstellten Callback an den Task (wahrscheinlich Lambda Funktion und mitContinueWith
). In diesem Callback wird der Rest der Funktion über Dispatching aufgerufen. Heisst aus dem Callback wird ein Event an die Nachrichtenschleife des UI Threads geschickt, dass er eine Funktion ausführen soll, welche schlussendlich den Rest (Teilbeinhaltet.
theta schrieb:
Meines Wissens kommen die zusätzlichen Threads vom Thread Pool.
Ja, allerdings wird so ein Thread durch ein
Task
Objekt angefordert.await
ruft man ja immer mit einemTask
auf. Wenn man es mit einer Funktion tut, dann auf dem zurückgegebenTask
Objekt. Man muss ja vorherTask.Start
aufrufen, dort wird der Thread aus dem Thread-Pool genommen. Dafür ist man aber selber verantwortlich, das machen die Schlüsselwörterasync
undawait
nicht für einem.Grüssli
-
Ahh alles klar, danke fuer die Erklaerung.
-
@Dravere: Sehe ich auch so.
-
Danke für die vielen Antworten! Eine Sache verstehe ich immer noch nicht:
async Task button_Click([blabla...]) { blablabla... }
blablabla... wird ja synchron ausgeführt. Aber wird der zurückgegebene Task (von button_Click), wenn er vom Ereignis gestartet wird, nicht bereits selber in einem neuen Thread gestartet?
-
@paulrei,
1. Der Eventhandler gibt kein Task zurück.
2. Nein, der Eventhandler wird nicht in einem neuen Thread gestartet sondern läuft ganz normal im UI-Thread wie bisher auch schon.Steht aber eigentlich alles im von dir verlinkten Tutorial
Edit: Beim nochmaligen durchlesen, bin ich mir jetzt nicht sicher, ob ich dich im Punkt zwei richtig verstanden habe.
Task.Start
führt natürlich dazu, dass die Aufgabe, mit welcher dasTask
Objekt assoziiert wurde, in einem eigenen Thread gestartet wird. Aber der Eventhandler gibt keinenTask
zurück, von daher ...Grüssli
Edit 2: Tippfehler Korrekturen, es ist eindeutig spät ...
-
Ja, ich habe den Artikel nicht ganz verstanden, sonst wäre ich ja nicht hier
@Dravere: Danke! Ich wusste gar nicht dass hier ein Unterschied zwischen Task und void besteht...