Condividi tramite


Paginazione con Azure SDK per .NET

Questo articolo illustra come usare la funzionalità di impaginazione di Azure SDK per .NET per funzionare in modo efficiente e produttivo con set di dati di grandi dimensioni. L'impaginazione è l'atto di dividere set di dati di grandi dimensioni in pagine, semplificando l'iterazione da parte del consumer a quantità ridotte di dati. A partire da C# 8, è possibile creare e usare flussi in modo asincrono usando flussi asincroni (asincroni). I flussi asincroni si basano sull'interfaccia IAsyncEnumerable<T> . Azure SDK per .NET espone un'implementazione di IAsyncEnumerable<T> con la relativa AsyncPageable<T> classe.

Tutti gli esempi in questo articolo si basano sui pacchetti NuGet seguenti:

Per la directory più recente dei pacchetti Azure SDK per .NET, vedere Le versioni più recenti di Azure SDK.

Tipi restituiti pageable

I client di cui è stata creata un'istanza da Azure SDK per .NET possono restituire i tipi di paging seguenti.

TIPO Descrizione
Pageable<T> Raccolta di valori recuperati nelle pagine
AsyncPageable<T> Raccolta di valori recuperati in modo asincrono nelle pagine

La maggior parte degli esempi in questo articolo è asincrona, usando le varianti del AsyncPageable<T> tipo. L'uso della programmazione asincrona per le operazioni associate a I/O è ideale. Un caso d'uso perfetto usa le API asincrone di Azure SDK per .NET perché queste operazioni rappresentano chiamate di rete HTTP/S.

Eseguire l'iterazione con AsyncPageableawait foreach

Per scorrere un AsyncPageable<T> oggetto usando la await foreach sintassi , considerare l'esempio seguente:

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

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

Nel codice C# precedente:

  • Il SecretClient.GetPropertiesOfSecretsAsync metodo viene richiamato e restituisce un AsyncPageable<SecretProperties> oggetto .
  • In un await foreach ciclo ogni SecretProperties viene restituito in modo asincrono.
  • Come ogni secret viene materializzato, il relativo Name viene scritto nella console.

Eseguire l'iterazione con AsyncPageablewhile

Per scorrere un oggetto AsyncPageable<T> quando la await foreach sintassi non è disponibile, usare un while ciclo.

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();
    }
}

Nel codice C# precedente:

Scorrere le AsyncPageable pagine

Se si vuole controllare la ricezione di pagine di valori dal servizio, usare il AsyncPageable<T>.AsPages metodo :

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);
    }
}

Nel codice C# precedente:

  • Il SecretClient.GetPropertiesOfSecretsAsync metodo viene richiamato e restituisce un AsyncPageable<SecretProperties> oggetto .
  • Il AsyncPageable<T>.AsPages metodo viene richiamato e restituisce un oggetto IAsyncEnumerable<Page<SecretProperties>>.
  • Ogni pagina viene iterata in modo asincrono usando await foreach.
  • Ogni pagina ha un set di Page<T>.Values, che rappresenta un IReadOnlyList<T> oggetto iterato su con un oggetto sincrono foreach.
  • Ogni pagina contiene anche un Page<T>.ContinuationTokenoggetto , che può essere usato per richiedere la pagina successiva.

Usare System.Linq.Async con AsyncPageable

Il System.Linq.Async pacchetto fornisce un set di metodi LINQ che operano sul IAsyncEnumerable<T> tipo. Poiché AsyncPageable<T> implementa IAsyncEnumerable<T>, è possibile usare System.Linq.Async per eseguire query e trasformare i dati.

Converti in un oggetto List<T>

Usare ToListAsync per convertire un oggetto AsyncPageable<T> in un oggetto List<T>. Questo metodo potrebbe effettuare diverse chiamate al servizio se i dati non vengono restituiti in una singola pagina.

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

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

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

Nel codice C# precedente:

  • Il SecretClient.GetPropertiesOfSecretsAsync metodo viene richiamato e restituisce un AsyncPageable<SecretProperties> oggetto .
  • Il ToListAsync metodo è atteso, che materializza una nuova List<SecretProperties> istanza.

Prendere i primi N elementi

Take può essere usato per ottenere solo i primi N elementi dell'oggetto AsyncPageable. L'uso Take eseguirà le più poche chiamate di servizio necessarie per ottenere N gli elementi.

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

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

Altri metodi

System.Linq.Asyncfornisce altri metodi che forniscono funzionalità equivalenti alle controparti sincroneEnumerable. Esempi di tali metodi includono Select, Where, OrderBye GroupBy.

Attenzione alla valutazione lato client

Quando si usa il System.Linq.Async pacchetto, tenere presente che le operazioni LINQ vengono eseguite nel client. La query seguente recupera tutti gli elementi solo per conteggiarli:

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

Avvertimento

Lo stesso avviso si applica agli operatori come Where. Preferire sempre filtri lato server, aggregazione o proiezioni di dati, se disponibili.

Come sequenza osservabile

Il System.Linq.Async pacchetto viene usato principalmente per fornire funzionalità di pattern osservatore sulle IAsyncEnumerable<T> sequenze. I flussi asincroni sono basati sul pull. Man mano che gli elementi vengono iterati, viene eseguito il pull dell'elemento disponibile successivo. Questo approccio è in sovrapposizione con il modello osservatore, che è basato su push. Man mano che gli elementi diventano disponibili, vengono inseriti nei sottoscrittori che fungono da osservatori. Il System.Linq.Async pacchetto fornisce il ToObservable metodo di estensione che consente di convertire un oggetto IAsyncEnumerable<T> in un oggetto IObservable<T>.

Si immagini un'implementazione IObserver<SecretProperties> :

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}");
}

È possibile utilizzare il ToObservable metodo di estensione come indicato di seguito:

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

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

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

Nel codice C# precedente:

  • Il SecretClient.GetPropertiesOfSecretsAsync metodo viene richiamato e restituisce un AsyncPageable<SecretProperties> oggetto .
  • Il ToObservable() metodo viene chiamato nell'istanza AsyncPageable<SecretProperties> di , restituendo un oggetto IObservable<SecretProperties>.
  • L'oggetto observable viene sottoscritto, passando l'implementazione dell'osservatore, restituendo la sottoscrizione al chiamante.
  • La sottoscrizione è un oggetto IDisposable. Quando viene eliminato, la sottoscrizione termina.

Eseguire l'iterazione su paginabile

Pageable<T> è una versione sincrona di AsyncPageable<T> che può essere usata con un ciclo normale foreach .

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

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

Importante

Anche se questa API sincrona è disponibile, usare le alternative api asincrone per un'esperienza migliore.

Vedere anche