Wat is het verschil tussen wait Task<T> en Taak<T>.Resultaat?

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>.Resultzal 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.Resultblokkeert de huidige thread. awaitis een asynchroon wachten; Resultis een blokkerende wachttijd.

Er is nog een kleiner verschil: als de taak wordt voltooid in een defecte staat (dwz met een uitzondering), dan zal awaitdie uitzondering (opnieuw) verhogen zoals het is, maar Resultverpakt 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 Resultals StartNewzijn 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.Resultof await tasksynchroon uitgevoerd, aangezien awaiteerst 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 awaitasynchroon wachtop de voltooiing van de taken. Een ander ding dat verschilt, is de afhandeling van uitzonderingen. Terwijl de eerste een AggregationExceptionverspreidt (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.Resultbinnen een asynchrone methode is een oorzaak voor impasses en moet ook worden vermeden.

Other episodes