Journalisation avec le kit SDK Azure pour .NET

Dans cet article, vous allez découvrir comment utiliser la fonctionnalité de pagination du kit de développement logiciel (SDK) pour .NET afin de travailler de façon efficace et productive avec des jeux de données volumineux. La pagination, à savoir le fait de diviser de gros jeux de données en pages, permet au consommateur d’effectuer plus facilement des itérations sur de petits volumes de données. À compter de la version 8 de C#, vous pouvez créer et consommer des flux de manière asynchrone à l’aide de flux asynchrones. Ces derniers reposent sur l’interface IAsyncEnumerable<T>. Le kit SDK Azure pour .NET expose une implémentation de IAsyncEnumerable<T> avec sa classe AsyncPageable<T>.

Tous les exemples de cet article s’appuient sur les packages NuGet suivants :

Pour connaître le dernier répertoire en date des packages du kit SDK Azure pour .NET, consultez Dernières versions du kit SDK Azure.

Types de retour paginables

Les clients instanciés à partir du kit SDK Azure pour .NET peuvent retourner les types paginables suivants.

Type Description
Pageable<T> Collection de valeurs récupérées dans les pages.
AsyncPageable<T> Collection de valeurs récupérées de manière asynchrone dans les pages.

La plupart des exemples de cet article sont asynchrones et utilisent des variantes du type AsyncPageable<T>. La programmation asynchrone est idéale pour les opérations liées aux E/S. Un cas d’usage parfait consiste à utiliser les API asynchrones du kit SDK Azure pour .NET, car ces opérations représentent des appels réseau HTTP/S.

Itération sur des AsyncPageable avec await foreach

Pour itérer sur des AsyncPageable<T> à l’aide de la syntaxe await foreach, considérez l’exemple suivant :

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

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

Dans le code C# précédent :

  • La méthode SecretClient.GetPropertiesOfSecretsAsync est appelée et retourne un objet AsyncPageable<SecretProperties>.
  • Dans une boucle await foreach, chaque SecretProperties est généré de manière asynchrone.
  • À mesure que chaque secret est matérialisé, son Name est écrit dans la console.

Itération sur des AsyncPageable avec while

Pour itérer sur des AsyncPageable<T> lorsque la syntaxe await foreach n’est pas disponible, utilisez une boucle while.

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

Dans le code C# précédent :

Itération sur des pages AsyncPageable

Si vous souhaitez contrôler la réception des pages de valeurs issues du service, utilisez la méthode 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);
    }
}

Dans le code C# précédent :

  • La méthode SecretClient.GetPropertiesOfSecretsAsync est appelée et retourne un objet AsyncPageable<SecretProperties>.
  • La méthode AsyncPageable<T>.AsPages est appelée et retourne un objet IAsyncEnumerable<Page<SecretProperties>>.
  • L’itération est effectuée de manière asynchrone sur chaque page, à l’aide de await foreach.
  • Chaque page comporte un ensemble de Page<T>.Values, qui représente une IReadOnlyList<T> sur laquelle une boucle foreach synchrone effectue des itérations.
  • Chaque page contient également un Page<T>.ContinuationToken, qui peut être utilisé pour demander la page suivante.

Utilisation de System.Linq.Async avec AsyncPageable

Le package System.Linq.Async fournit un ensemble de méthodes LINQ qui fonctionnent sur le type IAsyncEnumerable<T>. Étant donné que AsyncPageable<T> implémente IAsyncEnumerable<T>, vous pouvez utiliser System.Linq.Async pour interroger et transformer les données.

Conversion en List<T>

Utilisez ToListAsync pour convertir des AsyncPageable<T> en List<T>. Cette méthode peut effectuer plusieurs appels de service si les données ne sont pas retournées dans une seule page.

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

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

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

Dans le code C# précédent :

  • La méthode SecretClient.GetPropertiesOfSecretsAsync est appelée et retourne un objet AsyncPageable<SecretProperties>.
  • La méthode ToListAsync est attendue, ce qui matérialise une nouvelle instance List<SecretProperties>.

N premiers éléments

Take peut être utilisé pour obtenir uniquement les N premiers éléments de AsyncPageable. Le recours à Take permet d’effectuer le moins d’appels de service possible pour récupérer N éléments.

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

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

Autres méthodes

System.Linq.Async fournit d’autres méthodes qui offrent des fonctionnalités comparables à celles de leurs équivalents Enumerable synchrones, par exemple Select, Where, OrderBy et GroupBy.

Attention à l’évaluation côté client

Si vous utilisez le package System.Linq.Async, veillez à ce que les opérations LINQ soient exécutées sur le client. La requête suivante récupère tous les éléments juste pour les compter :

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

Avertissement

Le même avertissement s’applique aux opérateurs tels que Where. Dans la mesure du possible, préférez toujours le filtrage, l’agrégation et les projections de données côté serveur.

Utilisation comme séquence observable

Le package System.Linq.Async est principalement utilisé pour fournir des fonctionnalités de modèle d’observateur sur des séquences IAsyncEnumerable<T>. Les flux asynchrones fonctionnent par extraction. Après une itération sur un élément, l’élément disponible suivant est extrait. Cette approche s’oppose au modèle d’observateur, axé lui sur la transmission de type push. À mesure qu’ils deviennent disponibles, les éléments sont transmis aux abonnés qui jouent le rôle d’observateurs. Le package System.Linq.Async fournit la méthode d’extension ToObservable qui permet de convertir des IAsyncEnumerable<T> en IObservable<T>.

Imaginez une implémentation de 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}");
}

Vous pouvez utiliser la méthode d’extension ToObservable :

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

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

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

Dans le code C# précédent :

  • La méthode SecretClient.GetPropertiesOfSecretsAsync est appelée et retourne un objet AsyncPageable<SecretProperties>.
  • La méthode ToObservable() est appelée sur l’instance AsyncPageable<SecretProperties> et retourne un objet IObservable<SecretProperties>.
  • Un abonnement à observable est créé, en passant l’implémentation de l’observateur et en retournant l’abonnement à l’appelant.
  • L’abonnement est un IDisposable. Lorsqu’il est supprimé, l’abonnement se termine.

Itération sur Pageable

Pageable<T> est une version synchrone de AsyncPageable<T> qui peut être utilisée avec une boucle foreach normale.

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

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

Important

Bien que cette API synchrone soit disponible, utilisez plutôt les API asynchrones pour une meilleure expérience.

Voir aussi