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?


  • Administrator

    theta schrieb:

    @Helium: Möchtest Du auf was bestimmtes hinaus?

    Mein Wissen über async und await sind zwar noch nicht so wirklich vollständig, aber bisher habe ich immer gelesen, dass async und await keine neuen Threads erstellen. Um etwas im Hintergrund auszuführen, muss man dies selbst tun, in dem man zum Beispiel einen Task 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.


  • Administrator

    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 einen Task . Der UI Thread hängt nun einen vom Kompiler erstellten Callback an den Task (wahrscheinlich Lambda Funktion und mit ContinueWith ). 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 (Teil 😎 beinhaltet.

    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 einem Task auf. Wenn man es mit einer Funktion tut, dann auf dem zurückgegeben Task Objekt. Man muss ja vorher Task.Start aufrufen, dort wird der Thread aus dem Thread-Pool genommen. Dafür ist man aber selber verantwortlich, das machen die Schlüsselwörter async und await 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?


  • Administrator

    @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 das Task Objekt assoziiert wurde, in einem eigenen Thread gestartet wird. Aber der Eventhandler gibt keinen Task 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...


Anmelden zum Antworten