Partilhar via


Paginação com o SDK do Azure para .NET

Neste artigo, você aprenderá a usar a funcionalidade de paginação do SDK do Azure para .NET para trabalhar de forma eficiente e produtiva com grandes conjuntos de dados. A paginação é o ato de dividir grandes conjuntos de dados em páginas, tornando mais fácil para o consumidor iterar através de quantidades menores de dados. A partir do C# 8, você pode criar e consumir fluxos de forma assíncrona usando fluxos assíncronos (assíncronos). Os fluxos assíncronos IAsyncEnumerable<T> são baseados na interface. O SDK do Azure para .NET expõe uma implementação de IAsyncEnumerable<T> com sua AsyncPageable<T> classe.

Todos os exemplos neste artigo dependem dos seguintes pacotes NuGet:

Para obter o diretório mais recente dos pacotes do SDK do Azure para .NET, consulte Versões mais recentes do SDK do Azure.

Tipos de retorno pagináveis

Os clientes instanciados a partir do SDK do Azure para .NET podem retornar os seguintes tipos pagináveis.

Tipo Description
Pageable<T> Uma coleção de valores recuperados em páginas
AsyncPageable<T> Uma coleção de valores recuperados de forma assíncrona em páginas

A maioria dos exemplos neste artigo são assíncronos, usando variações do AsyncPageable<T> tipo. O uso de programação assíncrona para operações vinculadas a E/S é o ideal. Um caso de uso perfeito é usar as APIs assíncronas do SDK do Azure para .NET, pois essas operações representam chamadas de rede HTTP/S.

Repetir com AsyncPageableawait foreach

Para iterar sobre um AsyncPageable<T> usando a await foreach sintaxe, considere o seguinte exemplo:

async Task IterateSecretsWithAwaitForeachAsync()
{
    AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();

    await foreach (SecretProperties secret in allSecrets)
    {
        Console.WriteLine($"IterateSecretsWithAwaitForeachAsync: {secret.Name}");
    }
}

No código C# anterior:

  • O SecretClient.GetPropertiesOfSecretsAsync método é invocado e retorna um AsyncPageable<SecretProperties> objeto.
  • Em um loop, cada SecretProperties um await foreach é produzido de forma assíncrona.
  • À medida que cada um secret se materializa, o seu Name é gravado na consola.

Repetir com AsyncPageablewhile

Para iterar sobre um AsyncPageable<T> quando a await foreach sintaxe não estiver disponível, use um while loop.

async Task IterateSecretsWithWhileLoopAsync()
{
    AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();

    IAsyncEnumerator<SecretProperties> enumerator = allSecrets.GetAsyncEnumerator();
    try
    {
        while (await enumerator.MoveNextAsync())
        {
            SecretProperties secret = enumerator.Current;
            Console.WriteLine($"IterateSecretsWithWhileLoopAsync: {secret.Name}");
        }
    }
    finally
    {
        await enumerator.DisposeAsync();
    }
}

No código C# anterior:

Iterar sobre AsyncPageable páginas

Se você quiser ter controle sobre o recebimento de páginas de valores do serviço, use o AsyncPageable<T>.AsPages método:

async Task IterateSecretsAsPagesAsync()
{
    AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();

    await foreach (Page<SecretProperties> page in allSecrets.AsPages())
    {
        foreach (SecretProperties secret in page.Values)
        {
            Console.WriteLine($"IterateSecretsAsPagesAsync: {secret.Name}");
        }

        // The continuation token that can be used in AsPages call to resume enumeration
        Console.WriteLine(page.ContinuationToken);
    }
}

No código C# anterior:

  • O SecretClient.GetPropertiesOfSecretsAsync método é invocado e retorna um AsyncPageable<SecretProperties> objeto.
  • O AsyncPageable<T>.AsPages método é invocado e retorna um IAsyncEnumerable<Page<SecretProperties>>arquivo .
  • Cada página é iterada de forma assíncrona, usando await foreacho .
  • Cada página tem um conjunto de Page<T>.Values, que representa um IReadOnlyList<T> que é iterado com um .foreach
  • Cada página também contém um Page<T>.ContinuationToken, que pode ser usado para solicitar a próxima página.

Utilizar System.Linq.Async com AsyncPageable

O System.Linq.Async pacote fornece um conjunto de métodos LINQ que operam no IAsyncEnumerable<T> tipo. Como AsyncPageable<T> implementa IAsyncEnumerable<T>o , você pode usar System.Linq.Async para consultar e transformar os dados.

Converter em um List<T>

Use ToListAsync para converter um AsyncPageable<T> em um List<T>arquivo . Esse método pode fazer várias chamadas de serviço se os dados não forem retornados em uma única página.

async Task ToListAsync()
{
    AsyncPageable<SecretProperties> allSecrets =
        client.GetPropertiesOfSecretsAsync();

    List<SecretProperties> secretList = await allSecrets.ToListAsync();

    secretList.ForEach(secret =>
        Console.WriteLine($"ToListAsync: {secret.Name}"));
}

No código C# anterior:

  • O SecretClient.GetPropertiesOfSecretsAsync método é invocado e retorna um AsyncPageable<SecretProperties> objeto.
  • Aguarda-se o ToListAsync método, que materializa uma nova List<SecretProperties> instância.

Pegue os primeiros N elementos

Take pode ser usado para obter apenas os primeiros N elementos do AsyncPageable. Usar Take fará o menor número de chamadas de serviço necessárias para obter N itens.

async Task TakeAsync(int count = 30)
{
    AsyncPageable<SecretProperties> allSecrets =
        client.GetPropertiesOfSecretsAsync();

    await foreach (SecretProperties secret in allSecrets.Take(count))
    {
        Console.WriteLine($"TakeAsync: {secret.Name}");
    }
}

Mais métodos

System.Linq.Asyncfornece outros métodos que fornecem funcionalidade equivalente às suas contrapartes síncronasEnumerable. Exemplos de tais métodos incluem Select, Where, OrderBy, e GroupBy.

Cuidado com a avaliação do lado do cliente

Ao usar o System.Linq.Async pacote, cuidado para que as operações LINQ sejam executadas no cliente. A consulta a seguir buscaria todos os itens apenas para contá-los:

// ⚠️ DON'T DO THIS! 😲
int expensiveSecretCount =
    await client.GetPropertiesOfSecretsAsync()
        .CountAsync();

Aviso

O mesmo aviso se aplica a operadores como Where. Prefira sempre filtragem, agregação ou projeções de dados do lado do servidor, se disponíveis.

Como uma sequência observável

O System.Linq.Async pacote é usado principalmente para fornecer recursos de padrão de observador em IAsyncEnumerable<T> sequências. Os fluxos assíncronos são baseados em pull. À medida que seus itens são iterados, o próximo item disponível é puxado. Esta abordagem está em justaposição com o padrão do observador, que é baseado em push. À medida que os itens ficam disponíveis, eles são enviados para assinantes que atuam como observadores. O System.Linq.Async pacote fornece o ToObservable método de extensão que permite converter um IAsyncEnumerable<T> em um IObservable<T>arquivo .

Imagine uma IObserver<SecretProperties> implementação:

sealed file class SecretPropertyObserver : IObserver<SecretProperties>
{
    public void OnCompleted() =>
        Console.WriteLine("Done observing secrets");

    public void OnError(Exception error) =>
        Console.WriteLine($"Error observing secrets: {error}");

    public void OnNext(SecretProperties secret) =>
        Console.WriteLine($"Observable: {secret.Name}");
}

Você pode consumir o método de ToObservable extensão da seguinte maneira:

IDisposable UseTheToObservableMethod()
{
    AsyncPageable<SecretProperties> allSecrets =
        client.GetPropertiesOfSecretsAsync();

    IObservable<SecretProperties> observable = allSecrets.ToObservable();

    return observable.Subscribe(
        new SecretPropertyObserver());
}

No código C# anterior:

  • O SecretClient.GetPropertiesOfSecretsAsync método é invocado e retorna um AsyncPageable<SecretProperties> objeto.
  • O ToObservable() método é chamado na AsyncPageable<SecretProperties> instância, retornando um IObservable<SecretProperties>arquivo .
  • O observable é subscrito, passando na implementação do observador, devolvendo a subscrição ao chamador.
  • A subscrição é um IDisposableficheiro . Quando é descartado, a assinatura termina.

Iterar sobre paginável

Pageable<T> é uma versão síncrona que AsyncPageable<T> pode ser usada com um loop normal foreach .

void IterateWithPageable()
{
    Pageable<SecretProperties> allSecrets = client.GetPropertiesOfSecrets();

    foreach (SecretProperties secret in allSecrets)
    {
        Console.WriteLine($"IterateWithPageable: {secret.Name}");
    }
}

Importante

Enquanto essa API síncrona estiver disponível, use as alternativas de API assíncrona para uma melhor experiência.

Consulte também