Un poco de información de fondo.
Estoy aprendiendo la pila de API web y estoy tratando de encapsular todos los datos en forma de un objeto "Resultado" con parámetros tales como Success y ErrorCodes.
Sin embargo, diferentes métodos producirían diferentes resultados y códigos de error, pero el objeto de resultado generalmente se instanciaría de la misma manera.
Para ahorrar algo de tiempo y también para aprender más sobre las capacidades asíncronas / de espera en C #, estoy tratando de envolver todos los cuerpos de método de mis acciones de API web en un delegado de acción asíncrono, pero quedé atrapado en un pequeño inconveniente ...
Dadas las siguientes clases:
public class Result
{
public bool Success { get; set; }
public List<int> ErrorCodes{ get; set; }
}
public async Task<Result> GetResultAsync()
{
return await DoSomethingAsync<Result>(result =>
{
// Do something here
result.Success = true;
if (SomethingIsTrue)
{
result.ErrorCodes.Add(404);
result.Success = false;
}
}
}
Quiero escribir un método que realice una acción en un objeto Result y devolverlo. Normalmente a través de métodos sincrónicos sería
public T DoSomethingAsync<T>(Action<T> resultBody) where T : Result, new()
{
T result = new T();
resultBody(result);
return result;
}
Pero, ¿cómo transformo este método en un método asincrónico usando async / await?
Esto es lo que he intentado:
public async Task<T> DoSomethingAsync<T>(Action<T, Task> resultBody)
where T: Result, new()
{
// But I don't know what do do from here.
// What do I await?
}
fuente
new
poniendo en marcha elT
, ¿por qué su método debe ser asíncrono? AFAIK en el código utilizando API asíncronas, solo necesita propagar elasync
ness de otros métodos que utiliza.Stream.ReadAsync()
en un método, ese método en sí mismo debería ser asíncrono, y devolver unTask<T>
dóndeT
es lo que habría devuelto si el método fuera síncrono. La idea es que de esta manera, cada persona que llama de su método puede "esperar asincrónicamente" (no sé cuál es un buen término para esto) paraStream.ReadAsync()
que se complete el subyacente . Una metáfora para esto que puede usar es que el asíncrono es "infeccioso" y se propaga desde E / S incorporadas de bajo nivel a otro código cuyos resultados dependen de los de dicha E / S.Respuestas:
El
async
equivalente deAction<T>
esFunc<T, Task>
, así que creo que esto es lo que estás buscando:fuente
void
método es unTask
método de retorno; por lo tanto, el equivalente asíncrono deAction
isFunc<Task>
y el equivalente asíncrono deAction<T>
isFunc<T, Task>
. Más información aquí .Task
cuando no tiene un valor de retorno. Si usa laasync
palabra clave, laTask
instancia real será creada por una máquina de estado, no por la función directamente.Así que creo que la forma de implementar esto es:
fuente
Task.Run
(y aún másStartNew
) en ASP.NET.