Recientemente estuve leyendo un código que usa muchos métodos asíncronos, pero que a veces necesita ejecutarlos sincrónicamente. El código hace:
Foo foo = GetFooAsync(...).GetAwaiter().GetResult();
¿Es esto lo mismo que
Foo foo = GetFooAsync(...).Result;
c#
async-await
Jay Bazuzi
fuente
fuente
GetResult
: "Este tipo y sus miembros están destinados a ser utilizados por el compilador". Otra persona no debería estar usándolo.async
/await
método en MVC, por ejemplo)Respuestas:
Más o menos. Sin embargo, una pequeña diferencia: si
Task
falla,GetResult()
solo arrojará la excepción causada directamente, mientrasTask.Result
que arrojará unAggregateException
. Sin embargo, ¿cuál es el punto de usar cualquiera de esos cuando esasync
? La opción 100x mejor es usarawait
.Además, no estás destinado a usar
GetResult()
. Está destinado a ser solo para uso del compilador, no para ti. Pero si no quieres lo molestoAggregateException
, úsalo .fuente
async Task
unidades de prueba de soporte , y lo han hecho por algún tiempo.The 100x better option is to use await.
Odio las declaraciones como esta, si pudiera abofetearloawait
lo haría. Pero, cuando estoy tratando de obtener el código asíncrono de trabajo contra el código asíncrono no como lo que sucede con frecuencia para mí una gran cantidad de Xamarin, me acaban de tener que usar cosas comoContinueWith
una gran cantidad con el fin de hacer que no punto muerto la interfaz de usuario. Editar: Sé que esto es viejo, pero eso no alivia mi frustración al encontrar respuestas que indican esto sin alternativas para situaciones en las que no se puede usarawait
.Task.GetAwaiter().GetResult()
se prefiere sobreTask.Wait
yTask.Result
porque propaga excepciones en lugar de envolverlas en unAggregateException
. Sin embargo, los tres métodos causan la posibilidad de problemas de inmovilización y de grupo de subprocesos. Todos deben ser evitados a favor deasync/await
.La cita a continuación explica por qué
Task.Wait
yTask.Result
no simplemente contiene el comportamiento de propagación de excepción deTask.GetAwaiter().GetResult()
(debido a una "barra de compatibilidad muy alta").https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html
fuente
Task.GetAwaiter().GetResult()
es equivalente aawait task
. Supongo que la primera opción se usa cuando el método no se puede marcar conasync
(constructor, por ejemplo). ¿Es eso correcto? Si es así, entonces choca con la respuesta principal @ It'sNotALieTask.GetAwaiter().GetResult()
es más equivalente aTask.Wait
yTask.Result
(ya que los tres se bloquearán sincrónicamente y tienen el potencial de puntos muertos), peroTask.GetAwaiter().GetResult()
tiene el comportamiento de propagación de excepción de la tarea de espera.https://github.com/aspnet/Security/issues/59
fuente
Task.WhenAll(task1, task2).GetAwaiter().GetResult();
.Otra diferencia es cuando la
async
función regresa enTask
lugar deTask<T>
no poder usarMientras
todavía funciona.
Sé que el código de ejemplo en la pregunta es para el caso
Task<T>
, sin embargo, la pregunta se hace generalmente.fuente
Result
con elGetIntAsync()
que devuelveTask<int>
no soloTask
. Le sugiero que lea mi respuesta nuevamente.GetFooAsync(...).Result
dentro de una función que regresaTask
. Esto ahora tiene sentido, ya que no hay propiedades nulas en C # (Task.Result
es una propiedad), pero por supuesto puede llamar a un método nulo.Como ya se mencionó si puede usar
await
. Si necesita ejecutar el código sincrónicamente como lo menciona.GetAwaiter().GetResult()
,.Result
o si.Wait()
existe un riesgo de puntos muertos, como muchos han dicho en los comentarios / respuestas. Como a la mayoría de nosotros nos gustan las líneas, puede usarlas para.Net 4.5<
Adquisición de un valor a través de un método asíncrono:
Llamar sincrónicamente a un método asíncrono
No se producirán problemas de punto muerto debido al uso de
Task.Run
.Fuente:
https://stackoverflow.com/a/32429753/3850405
fuente
fuente: c # 7.0 en una cáscara de nuez
fuente