Freigeben über


Paginierung mit dem Azure SDK für .NET

In diesem Artikel lernen Sie, wie Sie das Azure SDK für die .NET-Funktionen zur Paginierung verwenden können, um effizient und produktiv mit großen Datasets zu arbeiten. Paginierung bezeichnet das Aufteilen großer Datensätze in Seiten, wodurch es für den Consumer einfacher ist, durch kleinere Datenmengen zu iterieren. Ab C# 8 können Sie Streams mithilfe von asynchronen Streams asynchron erstellen und nutzen. Asynchrone Streams basieren auf der IAsyncEnumerable<T>-Schnittstelle. Das Azure-SDK für .NET macht eine Implementierung von IAsyncEnumerable<T> mit der dazugehörigen Klasse AsyncPageable<T> verfügbar.

Alle Beispiele in diesem Artikel basieren auf den folgenden NuGet-Paketen:

Informationen zum aktuellen Verzeichnis des Azure-SKD für .NET-Pakete finden Sie unter Alle Bibliotheken.

Auslagerbare Rückgabetypen

Clients, die über das Azure SDK für .NET instanziiert wurden, können die folgenden auslagerbaren Typen zurückgeben.

Typ BESCHREIBUNG
Pageable<T> Eine Sammlung von Werten, die in Seiten abgerufen werden
AsyncPageable<T> Eine Sammlung von Werten, die asynchron in Seiten abgerufen werden

Die meisten Codeausschnitte in diesem Artikel sind asynchron und verwenden Variationen des AsyncPageable<T>-Typs. Die Verwendung asynchroner Programmierung für E/A-gebundene Vorgänge ist ideal. Ein idealer Anwendungsfall ist die Verwendung asynchroner APIs im Azure-SDK für .NET, da diese Vorgänge für HTTP/S-Aufrufe stehen.

Iterieren von AsyncPageable mit await foreach

Betrachten Sie den folgenden Codeausschnitt, in dem AsyncPageable<T> mit einer await foreach-Syntax iteriert wird:

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

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

Im oben stehenden C#-Code ist Folgendes passiert:

  • Die SecretClient.GetPropertiesOfSecretsAsync-Methode wird aufgerufen und gibt ein AsyncPageable<SecretProperties>-Objekt zurück.
  • In einer await foreach-Schleife wird jedes SecretProperties-Objekt asynchron angehalten.
  • Mit der Realisierung aller secret-Objekte werden deren Name-Objekte in die Konsole geschrieben.

Iterieren von AsyncPageable mit while

Verwenden Sie eine while-Schleife, um über AsyncPageable<T> zu iterieren, wenn die await foreach-Syntax nicht verfügbar ist.

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

Im oben stehenden C#-Code ist Folgendes passiert:

Iterieren über AsyncPageable-Seiten

Wenn Sie den Empfang von Seiten mit Werten vom Dienst steuern können möchten, verwenden Sie die Methode AsyncPageable<T>.AsPages:

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

Im oben stehenden C#-Code ist Folgendes passiert:

  • Die SecretClient.GetPropertiesOfSecretsAsync-Methode wird aufgerufen und gibt ein AsyncPageable<SecretProperties>-Objekt zurück.
  • Die AsyncPageable<T>.AsPages-Methode wird aufgerufen und gibt ein IAsyncEnumerable<Page<SecretProperties>>-Objekt zurück.
  • Die Iteration für jede Seite wird mithilfe von await foreach asynchron durchgeführt.
  • Jede Seite verfügt über mehrere Page<T>.Values-Eigenschaften, die für eine IReadOnlyList<T>-Liste stehen, die mithilfe von foreach (synchron) durchlaufen wird.
  • Jede Seite enthält auch eine Page<T>.ContinuationToken-Eigenschaft, die zum Anfordern der nächsten Seite verwendet werden kann.

Verwenden von System.Linq.Async mit AsyncPageable

Das System.Linq.Async-Paket bietet eine Reihe von LINQ-Methoden, die sich auf den IAsyncEnumerable<T>-Typ auswirken. Da AsyncPageable<T>IAsyncEnumerable<T> implementiert, können Sie System.Linq.Async verwenden, um die Daten abfragen und transformieren zu können.

Umwandeln in ein List<T>-Objekt

Verwenden Sie ToListAsync, um ein AsyncPageable<T>-Objekt in ein List<T>-Objekt zu konvertieren. Diese Methode kann mehrere Dienstaufrufe zur Folge haben, wenn die Daten nicht auf einer einzelnen Seite zurückgegeben werden.

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

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

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

Im oben stehenden C#-Code ist Folgendes passiert:

  • Die SecretClient.GetPropertiesOfSecretsAsync-Methode wird aufgerufen und gibt ein AsyncPageable<SecretProperties>-Objekt zurück.
  • Es wird auf die ToListAsync-Methode gewartet, die eine neue -Instanz List<SecretProperties> erstellt.

Abrufen der ersten N-Elemente

Take kann verwendet werden, um nur die ersten N-Elemente von AsyncPageable zu erhalten. Wenn Sie Take verwenden, werden die wenigsten Dienstaufrufe benötigt, um N-Elemente zu erhalten.

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

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

Weitere Methoden

System.Linq.Async bietet weitere Methoden, die Funktionen bieten, die äquivalent zu den synchronen Enumerable-Gegenstücken sind. Beispiele für solche Methoden sind Select, Where, OrderBy und GroupBy.

Vorsicht bei clientseitiger Auswertung

Wenn Sie das Paket System.Linq.Async verwenden, sollte Ihnen bewusst sein, dass LINQ-Vorgänge im Client ausgeführt werden. Mit der folgenden Abfrage werden alle Elemente abgerufen, um sie zu zählen:

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

Warnung

Dieselbe Warnung gilt für Operatoren wie Where. Es wird empfohlen, immer die serverseitige Filterung, Aggregation oder Projektionen von Daten vorzuziehen, falls verfügbar.

Observable-Sequenz

Das System.Linq.Async-Paket wird hauptsächlich verwendet, um Beobachtermusterfunktionen für IAsyncEnumerable<T>-Sequenzen zur Verfügung zu stellen. Asynchrone Streams sind Pull-basiert. Während die Elemente durchlaufen werden, wird das jeweils nächste verfügbare Element gepullt. Dieser Ansatz steht dem Beobachtungsmuster gegenüber, das Push-basiert ist. Sobald Elemente verfügbar sind, werden sie an Abonnenten gepusht, die als Beobachter fungieren. Das System.Linq.Async-Paket stellt die ToObservable-Erweiterungsmethode zur Konvertierung von IAsyncEnumerable<T> in eine IObservable<T>-Datei zur Verfügung.

Sehen Sie sich das Beispiel für eine IObserver<SecretProperties>-Implementierung an:

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

Sie können die ToObservable-Erweiterungsmethode wie folgt nutzen:

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

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

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

Im oben stehenden C#-Code ist Folgendes passiert:

  • Die SecretClient.GetPropertiesOfSecretsAsync-Methode wird aufgerufen und gibt ein AsyncPageable<SecretProperties>-Objekt zurück.
  • Die ToObservable()-Methode wird für die AsyncPageable<SecretProperties>-Instanz aufgerufen und gibt IObservable<SecretProperties> zurück.
  • Das observable-Objekt wird abonniert, und die Beobachterimplementierung wird übergeben, und das Abonnement wird an den Aufrufer zurückgeben.
  • Für das Abonnement gilt: IDisposable. Wenn das Abonnement gelöscht wird, endet das Abonnement.

Iterieren über auslagerbare Elemente

Pageable<T> ist eine synchrone Version von AsyncPageable<T> und kann mit einer normalen foreach-Schleife verwendet werden.

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

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

Wichtig

Diese synchrone API ist zwar verfügbar, es wird jedoch empfohlen, dass Sie asynchrone API-Alternativen verwenden. Mit diesen kann man besser arbeiten.

Siehe auch