Qual é a assinatura certa para uma ação do controlador que retorna um IAsyncEnumerable<T>
e um NotFoundResult
mas ainda é processada de maneira assíncrona?
Eu usei essa assinatura e ela não é compilada porque IAsyncEnumerable<T>
não é possível esperar:
[HttpGet]
public async Task<IActionResult> GetAll(Guid id)
{
try
{
return Ok(await repository.GetAll(id)); // GetAll() returns an IAsyncEnumerable
}
catch (NotFoundException e)
{
return NotFound(e.Message);
}
}
Este compila bem, mas sua assinatura não é assíncrona. Então, eu estou preocupado se ele irá bloquear os threads do pool de threads ou não:
[HttpGet]
public IActionResult GetAll(Guid id)
{
try
{
return Ok(repository.GetAll(id)); // GetAll() returns an IAsyncEnumerable
}
catch (NotFoundException e)
{
return NotFound(e.Message);
}
}
Eu tentei usar um await foreach
loop assim, mas que obviamente também não seria compilado:
[HttpGet]
public async IAsyncEnumerable<MyObject> GetAll(Guid id)
{
IAsyncEnumerable<MyObject> objects;
try
{
objects = contentDeliveryManagementService.GetAll(id); // GetAll() returns an IAsyncEnumerable
}
catch (DeviceNotFoundException e)
{
return NotFound(e.Message);
}
await foreach (var obj in objects)
{
yield return obj;
}
}
IAsyncEnumerable
é aguardável. Use await foreach(var item from ThatMethodAsync()){...}
.
IAsyncEnumerable<MyObject>
, basta retornar o resultado, por exemplo return objects
. Isso não converterá uma ação HTTP em um método gRPC ou SignalR de streaming. O middleware ainda consumirá os dados e enviará uma única resposta HTTP ao cliente
IAsyncEnumerable
reconhecido como 3.0.
MyObject
itens com o mesmoid
? Normalmente, você não enviaria umNotFound
para algo que retorne umIEnumerable
- apenas estaria vazio - ou você retornaria o item único com oid
/ solicitadoNotFound
.