In de bovenstaande method return-instructie gebruik ik de eigenschap Task<T>.Result
.
public async Task<string> GetName(int id)
{
Task<string> nameTask = Task.Factory.StartNew(() => string.Format("Name matching id {0} = Developer", id));
return await nameTask;
}
Hier gebruik ik await Task<T>
. Ik zal het mis hebben als ik denk dat wait de aanroepende thread zal vrijgeven, maar Task<T>.Result
zal het blokkeren, zou het juist zijn?
Antwoord 1, autoriteit 100%
Ik heb het bij het verkeerde eind als ik denk dat wait de aanroepende thread zal vrijgeven, maar Task.Result zal deze blokkeren, zou dat juist zijn?
Over het algemeen wel. await task;
zal de huidige thread “opleveren”. Task.Result
blokkeert de huidige thread. await
is een asynchroon wachten; Result
is een blokkerende wachttijd.
Er is nog een kleiner verschil: als de taak wordt voltooid in een defecte staat (dwz met een uitzondering), dan zal await
die uitzondering (opnieuw) verhogen zoals het is, maar Result
verpakt de uitzondering in een AggregateException
.
Als een kanttekening, vermijd Task.Factory.StartNew
. Het is bijna nooit de juiste methode om te gebruiken. Als u werk moet uitvoeren op een achtergrondthread, geeft u de voorkeur aan Task.Run
.
Zowel Result
als StartNew
zijn geschikt als u dynamisch taakparallellisme; anders moeten ze worden vermeden. Geen van beide is geschikt als u asynchroon programmeert.
Antwoord 2, autoriteit 6%
Ik heb het bij het verkeerde eind als ik denk dat wait de aanroepende thread zal vrijgeven, maar Task.Result zal deze blokkeren, zou dat juist zijn?
Je hebt gelijk, zolang de taak niet synchroon is voltooid. Als dit het geval is, wordt het gebruik van Task.Result
of await task
synchroon uitgevoerd, aangezien await
eerst zal controleren of de taak is voltooid. Anders, als de taak niet is voltooid, blokkeert het de aanroepende thread voor Task.Result
, terwijl het gebruik van await
asynchroon wachtop de voltooiing van de taken. Een ander ding dat verschilt, is de afhandeling van uitzonderingen. Terwijl de eerste een AggregationException
verspreidt (die een of meer uitzonderingen kan bevatten), zal de laatste deze uitpakken en de onderliggende uitzondering retourneren.
Als een kanttekening, asynchrone wrappers gebruiken via synchronisatie methoden is een slechte gewoonte en moet worden vermeden.Ook het gebruik van Task.Result
binnen een asynchrone methode is een oorzaak voor impasses en moet ook worden vermeden.