Gebruikt Async/Await Task.Run om asynchroon een nieuwe thread te starten?

Ik heb veel artikelen gelezen en kan dit deel nog steeds niet begrijpen.

Denk aan deze code:

   private async void button1_Click(object sender, EventArgs e)
    {
        await Dosomething();
    }
    private async Task<string> Dosomething()
    {
        await Task.Run((() => "Do Work"));
        return "I am done";
    }

Eerste vraag:

Als ik op de knop klik, zal het DoSomething aanroepen en wachten op een taak die een thread van de threadpool maakt door Task.Run aan te roepen (als ik me niet vergis) en dit alles verloopt asynchroon. Dus ik heb een thread gemaakt die mijn werk doet, maar het asynchroon doet? Maar bedenk dat ik geen resultaat nodig heb, ik wil gewoon dat het werk gedaan wordt zonder enig resultaat terug te krijgen, is het echt nodig om async/wait te gebruiken, en zo ja, hoe?

Tweede vraag:

Hoe werkt dat wanneer een thread asynchroon wordt uitgevoerd? Draait het op de hoofdgebruikersinterface maar op een aparte thread of draait het op een aparte thread en is apart asynchroon binnen die methode?


Antwoord 1, autoriteit 100%

  1. Het doel van het maken van Async-methoden is dat u ze later kunt afwachten. Zoiets van: “Ik ga dit water aan de kook brengen, de rest van mijn soepingrediënten klaarmaken en dan terug naar de pan gaan en wachten tot het water klaar is met koken, zodat ik het avondeten kan maken.” Je begint het water te koken, wat het asynchroon doet terwijl je andere dingen doet, maar uiteindelijk moet je stoppen en erop wachten. Als je wilt “fire-and-forget” dan zijn Async en Await niet nodig.

De eenvoudigste manier om vuur te maken en methode vergeten in C#?

  1. Het starten van een nieuwe taak zet die taak in de wachtrij voor uitvoering op een threadpoolthread. Threads worden uitgevoerd in de context van het proces (bijv. het uitvoerbare bestand dat uw toepassing uitvoert). Als dit een webtoepassing is die onder IIS draait, wordt die thread gemaakt in de context van het IIS-werkproces. Die thread wordt afzonderlijk van de hoofduitvoeringsthread uitgevoerd, dus het gaat uit en doet zijn ding, ongeacht wat uw hoofduitvoeringsthread doet, en tegelijkertijd gaat uw hoofduitvoeringsthread verder met zijn eigen werk.

Antwoord 2, autoriteit 64%

1

Er is een groot verschil als je niet awaitop de Taskof je awaiterop:

  • Geval u awaiter niet op: DoSomethingwordt aangeroepen maar de volgende zin wordt uitgevoerd terwijl DoSomethingTaskis niet voltooid.

  • Geval je awaiterop: DoSomethingwordt aangeroepen en de volgende zin wordt eenmaal uitgevoerd DoSomethingTaskis voltooid.

Dus de noodzaak van async/awaithangt af van hoe je DoSomethingwilt aanroepen: als je dat niet doet awaithet is alsof je het de fire & weg vergeten.

2

Is het actief op de hoofdinterface maar op een aparte thread of is het actief
op een aparte thread en apart is asynchroon daarbinnen
methode?

Asynchrone code betekent soms andere thread(zie deze Q&A Asynchrone vs Multithreading – Is er een verschil?). Dat wil zeggen, als de code wordt uitgevoerd in een aparte thread van de UI-thread of als het de verwerking van de UI-thread laat voortzetten terwijl deze wordt hervat, is het fijn omdat de UI-lus het scherm nog steeds kan bijwerken terwijl andere taken worden uitgevoerd in parallel zonder de gebruikersinterface te bevriezen.

Een asynchrone methode (d.w.z. asyncmethode) is een syntactische suiker om de compiler te vertellen dat await-instructies moeten worden behandeld als een statusmachine. De C#-compiler verandert uw async/await-code in een statusmachine waar code die wacht op een Task-resultaat wordt uitgevoerd na de code waarop wordt gewacht.

Interessante vragen en antwoorden

Misschien wil je deze andere Q&A’s nog eens bekijken:

OP zei…

[…] Maar betekent dit dat “async/wait” een thread zal starten en
Task.Run start ook een thread of zijn ze allebei dezelfde thread?

Het gebruik van asyncawaitbetekent niet “Ik maak een thread”. Het is gewoon een syntactische suiker om voortzettingen op een elegante manier te implementeren. Een taak kan al dan niet een thread zijn. Task.FromResult(true)maakt bijvoorbeeld een neptaak ​​om een ​​asynchrone methode te kunnen implementeren zonder dat het vereist is om een ​​thread te maken:

public Task<bool> SomeAsync()
{
    // This way, this method either decides if its code is asynchronous or 
    // synchronous, but the caller can await it anyway!
    return Task.FromResult(true);
}

Antwoord 3, autoriteit 46%

Het type Task<TResult>vereist dat u een TResultvan uw taak retourneert. Als u niets kunt retourneren, kunt u Taskin plaats daarvan (wat overigens de basisklasse is van Task<TResult>).

Maar onthoud dat een taak geen thread is. Een taak is een klus die moet worden gedaan, terwijl een thread een werk is. Naarmate uw programma loopt, komen banen en werknemers beschikbaar en niet beschikbaar. Achter de schermen wijst de bibliotheek uw taken toe aan beschikbare werknemers en omdat het creëren van nieuwe werknemers een kostbare operatie is, zal het er doorgaans de voorkeur aan geven de bestaande opnieuw te gebruiken via een threadpool.

Other episodes