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:
- Azure.Security.KeyVault.Secrets
- Microsoft.Extensões.Azure
- Microsoft.Extensões.Hospedagem
- System.Linq.Async
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 AsyncPageable
await 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
umawait foreach
é produzido de forma assíncrona. - À medida que cada um
secret
se materializa, o seuName
é gravado na consola.
Repetir com AsyncPageable
while
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:
- O SecretClient.GetPropertiesOfSecretsAsync método é invocado e retorna um
AsyncPageable<SecretProperties>
objeto. - O AsyncPageable<T>.GetAsyncEnumerator método é invocado, retornando um
IAsyncEnumerator<SecretProperties>
arquivo . - O MoveNextAsync() método é invocado repetidamente até que não haja itens para retornar.
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 foreach
o . - 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 novaList<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.Async
fornece 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 naAsyncPageable<SecretProperties>
instância, retornando umIObservable<SecretProperties>
arquivo . - O
observable
é subscrito, passando na implementação do observador, devolvendo a subscrição ao chamador. - A subscrição é um
IDisposable
ficheiro . 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.