Mi método regresa Task
. Quiero esperar hasta que termine. ¿Qué debo usar
.Wait()
o .GetAwaiter().GetResult()
? ¿Cuál es la diferencia entre ellos?
Mi método regresa Task
. Quiero esperar hasta que termine. ¿Qué debo usar
.Wait()
o .GetAwaiter().GetResult()
? ¿Cuál es la diferencia entre ellos?
Respuestas:
Ambos son una espera sincrónica del resultado de la operación (y debe evitarlos si es posible).
La diferencia está principalmente en el manejo de excepciones. Con Wait
, el seguimiento de la pila de excepciones no se modifica y representa la pila real en el momento de la excepción, por lo que si tiene un fragmento de código que se ejecuta en un subproceso de grupo de subprocesos, tendría una pila como
ThreadPoolThread.RunTask
YourCode.SomeWork
Por otro lado, .GetAwaiter().GetResult()
reelaborará el seguimiento de la pila para tener en cuenta todo el contexto asincrónico, ignorando que algunas partes del código se ejecutan en el subproceso de la interfaz de usuario y otras en un subproceso de ThreadPool, y algunas son simplemente E / S asincrónicas. Por lo tanto, el seguimiento de la pila reflejará un paso sincrónico en su código :
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
Esto tiende a hacer que los seguimientos de la pila de excepciones sean mucho más útiles, por decir lo menos. Puede ver dónde YourCode.SomeWork
se llamó en el contexto de su aplicación , en lugar de "la forma física en que se ejecutó".
Un ejemplo de cómo funciona esto está en la fuente de referencia (no contractual, por supuesto).
TaskAwaiter
es un detalle de implementación. Por otro lado, el mecanismo de espera / espera está documentado y utiliza el tipo de pato: GetAwaiter
es await
como GetEnumerator
está foreach
o Dispose
está using
. Todo esto se define en la especificación de C # independientemente del tipo de espera que se utilice; tenga en cuenta que Task.GetAwaiter
está "destinado al uso del compilador en lugar de al código de la aplicación". Pero el punto es que el uso previsto es hacer un await
, no Wait()
ni GetAwaiter().GetResult()
, pero GetResult
le brinda mejores pilas si lo necesita.