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:
- Azure.Security.KeyVault.Secrets
- Microsoft.Extensions.Azure
- Microsoft.Extensions.Hosting
- System.Linq.Async
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 jedesSecretProperties
-Objekt asynchron angehalten. - Mit der Realisierung aller
secret
-Objekte werden derenName
-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:
- Die SecretClient.GetPropertiesOfSecretsAsync-Methode wird aufgerufen und gibt ein
AsyncPageable<SecretProperties>
-Objekt zurück. - Die AsyncPageable<T>.GetAsyncEnumerator-Methode wird aufgerufen und gibt
IAsyncEnumerator<SecretProperties>
zurück. - Die MoveNextAsync()-Methode wird wiederholt aufgerufen, bis keine Elemente mehr zurückgegeben werden.
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 vonforeach
(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 -InstanzList<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 dieAsyncPageable<SecretProperties>
-Instanz aufgerufen und gibtIObservable<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.