Il mio metodo ritorna Task
. Voglio aspettare che finisca. Cosa dovrei usare
.Wait()
o .GetAwaiter().GetResult()
? Qual'è la differenza tra loro?
Il mio metodo ritorna Task
. Voglio aspettare che finisca. Cosa dovrei usare
.Wait()
o .GetAwaiter().GetResult()
? Qual'è la differenza tra loro?
Risposte:
Entrambi sono un'attesa sincrona per il risultato dell'operazione (e dovresti evitarli se possibile).
La differenza sta principalmente nella gestione delle eccezioni. Con Wait
, la traccia dello stack delle eccezioni è inalterata e rappresenta lo stack effettivo al momento dell'eccezione, quindi se hai una parte di codice che viene eseguita su un thread del pool di thread, avresti uno stack come
ThreadPoolThread.RunTask
YourCode.SomeWork
D'altra parte, .GetAwaiter().GetResult()
rielaborerà la traccia dello stack per prendere in considerazione tutto il contesto asincrono, ignorando che alcune parti del codice vengono eseguite sul thread dell'interfaccia utente e alcune su un thread ThreadPool e alcune sono semplicemente I / O asincrono. Quindi la traccia dello stack rifletterà un passaggio simile a quello sincrono nel codice :
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
Questo tende a rendere le tracce dello stack delle eccezioni molto più utili, per non dire altro. Puoi vedere dove è YourCode.SomeWork
stato chiamato nel contesto della tua applicazione , piuttosto che "il modo fisico in cui è stato eseguito".
Un esempio di come funziona è nella fonte di riferimento (non contrattuale, ovviamente).
TaskAwaiter
è un dettaglio di implementazione. D'altra parte, il meccanismo di attesa / attesa è documentato e utilizza la digitazione a papera: GetAwaiter
è await
come GetEnumerator
è foreach
o Dispose
è using
. Tutto questo è definito nella specifica C # indipendentemente dal particolare attendente utilizzato - si noti che Task.GetAwaiter
è "destinato all'uso da parte del compilatore piuttosto che all'uso nel codice dell'applicazione". Ma il punto è che l'uso previsto è fare un await
, non Wait()
né GetAwaiter().GetResult()
- ma GetResult
ti dà pile più belle se ne hai bisogno.