Asynchrone code

Om te vermijden dat de UI vastloopt kunnen we een long running method asynchroon maken. Als we dit doen wordt deze methode op een andere thread geplaatst waardoor de UI thread vrij blijft. Een asynchrone methode herkennen we aan 3 dingen:

  • Er staat async voor het return type van de methode
  • Het return type is een Task voor een void return type
  • Of een Task<T> voor een asynchrone methode die een waarde teruggeeft.
    • Bv Task<int>
    • Task<string>
    • Task<Person>
  • In de method body wordt er minstens 1 maal gebruik gemaakt van het await keyword
3 kenmerken van een asynchrone methode: async | Task | await

Tip: Voeg -async toe aan de naam van een methode die async kan werken. Dat maakt het een andere developer makkelijk om te weten welke methodes synchroon en welke asynchroon kunnen werken.

Belangrijk: Zorg ervoor dat je nooit een methode als async void markeert. Gebruik altijd async Task. De enige uitzondering waar je een async void moet gebruiken is in een Event Handler (bv. Button Clicked).

Als je op de button Execute Asynchronously klikt zal er achter de schermen exact hetzelfde gebeuren als bij de vorige button. Er worden 3 long running operations uitgevoerd. Ditmaal worden ze echter asynchroon uitgevoerd waardoor de UI-thread vrij blijft. De window grootte kan aangepast worden en de succes messages worden getoond van zodra de methode voltooid is.

Asynchrone methodes blokkeren de UI thread niet. Hierdoor blijft de app responsief

Async & Await

Je zal merken als je met asynchrone methodes werkt dat je steeds met async en await zal moeten werken. Om een asynchrone methode (zoals Task.Delay(x)) effectief asynchroon uit te voeren zal deze awaited moeten worden. Het await keyword kan enkel geplaats worden in een methode met het async keyword. Beide keywords zijn dus onlosmakelijk met elkaar verbonden.

Belangrijk: Als je vergeet om await voor een asynchrone methode zal deze uitgevoerd worden maar zal er niet gewacht worden op het resultaat van deze methode wat deze methode effectief ‘fire & forget’ maakt. Maak gebruik van Visual Studio om deze problemen op te sporen!

Foutboodschap: De auteur is vergeten om een asynchrone methode te awaiten

In een asynchrone methode kan zowel asynchrone code (await) als standaard code uitgevoerd worden.

Merk op in bovenstaande voorbeelden dat alle methodes waarin await voorkomt, het return type een async Task is, behalve in de BtnAsyncClicked event handler. Enkel hier mag een async void voorkomen aangezien het return type van een event handler void is. Elders in de app gebruik je nergens async void!

Aangezien een async methode dus awaited moet worden, en await enkel kan bestaan in een async methode kan gesteld worden dat asynchroon programmeren ‘aanstekelijk’ werkt. Van zodra 1 methode in een synchrone applicatie asynchroon wordt zulle alle methodes die van deze methode gebruik maken ook asynchroon moeten worden.Dit is een goede zaak. Multi Core processors hebben verschillende threads, wat de werkdruk aanzienlijk kan verspreiden voor de processor. Omarm asynchroon werken.

Denk er ook steeds aan om als je een void methode async wilt maken de void zal worden vervangen door een Task en als je een methode hebt die een int of een double teruggeeft, zal dit een return type Task<int> of Task<double>, Task<MyClass>, etc. worden.

Synchrone methode signaturen en hun asynchrone tegenhangers. Let op de -Async suffix.

Code forceren om asynchroon te runnen.

In de merendeel van de gevallen zul je asynchrone methodes maken omdat deze gebruik maken van andere, reeds bestaande, asynchrone methodes. Als je zelf een stuk code expliciet asynchroon wilt maken, kan je dit doen door deze code in een methode te stoppen en gebruik te maken van Task.Run().

Met Task.Run(methode) kan 100% synchrone code toch asynchroon gerund worden.