Aclaración sobre cómo funciona IAsyncEnumerable con la API web ASP.NET


9

Encontré un comportamiento interesante al explorar IAsyncEnumerable en un proyecto de API web ASP.NET. Considere los siguientes ejemplos de código:

    // Code Sample 1
    [HttpGet]
    public async IAsyncEnumerable<int> GetAsync()
    {
        for (int i = 0; i < 10; i++)
        {
            await Task.Delay(1000);
            yield return i;
        }
    }


    // Code Sample 2
    [HttpGet]
    public async IAsyncEnumerable<string> GetAsync()
    {
        for (int i = 0; i < 10; i++)
        {
            await Task.Delay(1000);
            yield return i.ToString();
        }
    }

La muestra 1 (int array) vuelve {}como resultado JSON.

La muestra 2 devuelve el resultado esperado ["0","1","2","3","4","5","6","7","8","9"]. Sin embargo, toda la matriz JSON se devuelve a la vez después de 10 segundos de espera. ¿No debería devolverse a medida que los datos estén disponibles como se esperaba de la interfaz IAsyncEnumerable? ¿O hay alguna forma específica de consumir esta API web?


44
¿No debería devolverse a medida que los datos estén disponibles como se esperaba de la interfaz IAsyncEnumerable? ... y lo hace ... pero para json serializer
Selvin

1
y la Muestra 1 ... parece un error para el tipo que no es de referencia (si cambia IAsyncEnumerable<int>a IAsyncEnumerable<object>- debería funcionar pero hay un recuadro involucrado)
Selvin

@Selvin, ¿podrías dar más detalles? ¿O apunta a una muestra de código? Traté de consumir esta API con el cliente C #, el resultado es el mismo, tengo que esperar 10 segundos ...
Ravi M Patel

tiene que esperar 10 segundos es obviosu ... la serialización está en el lado del servidor y no es asíncrona ... ¿elabora sobre qué?
Selvin

1
el error está aquí ... obviamente por eso
Selvin

Respuestas:


3

Una llamada de API web no devolverá json parcial cada segundo. Es el serializador json el que tiene que esperar 10x1 segundos (o el código que llama al serializador json, que es parte de ASP .NET). Una vez que el código marco y el serializador obtengan todos los datos, se servirán en serie, como respuesta única, al cliente.

En los tipos de retorno de acción del Controlador en la API web ASP.NET Core podemos leer:

En ASP.NET Core 3.0 y posterior, devolviendo IAsyncEnumerable de una acción:

  • Ya no da como resultado una iteración síncrona.
  • Se vuelve tan eficiente como devolver IEnumerable.

ASP.NET Core 3.0 y posterior almacena el resultado de la siguiente acción antes de proporcionarlo al serializador:

public IEnumerable<Product> GetOnSaleProducts() =>
  _context.Products.Where(p => p.IsOnSale);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.