Esto es lo que quiero decir:
public Task<SomeObject> GetSomeObjectByTokenAsync(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return Task.FromResult(new SomeObject()
{
IsAuthorized = false
});
}
else
{
return repository.GetSomeObjectByTokenAsync(token).ContinueWith(t =>
{
t.Result.IsAuthorized = true;
return t.Result;
});
}
}
Por encima de método puede ser esperado y creo que se asemeja mucho a lo que el T pide a base de una sincrónica P attern sugiere hacer? (Los otros patrones que conozco son los patrones APM y EAP ).
Ahora, ¿qué pasa con el siguiente código:
public async Task<SomeObject> GetSomeObjectByToken(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return new SomeObject()
{
IsAuthorized = false
};
}
else
{
SomeObject result = await repository.GetSomeObjectByTokenAsync(token);
result.IsAuthorized = true;
return result;
}
}
Las diferencias clave aquí son que el método es async
y utiliza las await
palabras clave, entonces, ¿qué cambia esto en contraste con el método escrito anteriormente? Sé que también puede ser esperado. Cualquier método que devuelva Tarea puede, en realidad, a menos que me equivoque.
Soy consciente de la máquina de estado creada con esas instrucciones de cambio cada vez que un método se etiqueta como async
, y sé que en await
sí mismo no usa ningún hilo: no se bloquea en absoluto, el hilo simplemente va a hacer otras cosas, hasta que sea volvió a llamar para continuar la ejecución del código anterior.
Pero, ¿cuál es la diferencia subyacente entre los dos métodos, cuando los invocamos usando la await
palabra clave? ¿Hay alguna diferencia, y si la hay, cuál es la preferida?
EDIT: Me siento como el primer fragmento de código se prefiere, ya que efectivamente eludir la asíncrono / Await palabras clave, sin ninguna repercusión - volvemos una tarea que continuará su ejecución de forma sincrónica, o una tarea ya realizada en el camino caliente (que puede ser en caché).
result.IsAuthorized = true
se ejecutará en el grupo de subprocesos, mientras que en el segundo ejemplo podría ejecutarse en el mismo subproceso que invocóGetSomeObjectByToken
(si teníaSynchronizationContext
instalado, por ejemplo, era un subproceso de interfaz de usuario). El comportamiento siGetSomeObjectByTokenAsync
arroja una excepción también será ligeramente diferente. En general,await
se prefiereContinueWith
, ya que casi siempre es más legible.