Bien démarrer avec le Stockage File d’attente Azure en utilisant .NET

Vue d’ensemble

Le Stockage File d’attente Azure fournit une messagerie cloud entre les composants d’application. Lors de la conception d’applications pour la mise à l’échelle, des composants d’application sont souvent découplés, de sorte qu’ils peuvent être mis à l’échelle indépendamment. Le Stockage File d’attente offre une messagerie asynchrone entre les composants d’application, qu’ils soient exécutés dans le cloud, sur un poste de travail, sur un serveur local ou sur un appareil mobile. Le Stockage File d’attente prend également en charge la gestion des tâches asynchrones et la création de workflows de processus.

À propos de ce didacticiel

Ce tutoriel montre comment écrire du code .NET pour des scénarios courants d’utilisation du Stockage File d’attente. Les scénarios traités sont les suivants : création et suppression de files d’attente, et ajout, lecture et suppression des messages de file d’attente.

Durée estimée : 45 minutes

Prérequis

Présentation du stockage File d’attente

Les files d’attente de stockage Azure sont un service permettant de stocker un grand nombre de messages accessibles depuis n’importe où dans le monde via des appels authentifiés avec HTTP ou HTTPS. Un simple message de file d’attente peut avoir une taille de 64 Ko et une file d’attente peut contenir des millions de messages, jusqu’à la limite de capacité totale d’un compte de stockage. Le stockage File d’attente est couramment utilisé pour créer un backlog de travail à traiter de façon asynchrone.

Concepts du service File d’attente

Le service de File d’attente Azure contient les composants suivants :

Azure Queue service components

  • Compte de stockage : Tous les accès à Azure Storage passent par un compte de stockage. Pour plus d’informations sur les comptes de stockage, consultez Vue d’ensemble des comptes de stockage.

  • File d’attente : une file d’attente contient un ensemble de messages. Tous les messages doivent être dans une file d’attente. Notez que le nom de la file d’attente doit être en minuscules. Pour plus d'informations sur l’affectation de noms à des files d’attente, consultez Affectation de noms pour les files d'attente et les métadonnées.

  • Message : message dans n’importe quel format d’une taille maximale de 64 Ko. La durée maximale pendant laquelle un message peut rester dans la file d’attente est de 7 jours. Pour les versions du 29 juillet 2017 ou ultérieures, la durée de vie maximale peut être n’importe quel nombre positif, ou -1 indiquant que le message n’expire pas. Si ce paramètre est omis, la valeur par défaut de la durée de vie est de sept jours.

  • Format d’URL : les files d’attente sont adressables à l’aide du format d’URL suivant : http://<storage account>.queue.core.windows.net/<queue>

    L'URL suivante désigne une file d'attente du schéma :

    http://myaccount.queue.core.windows.net/incoming-orders

Créer un compte de stockage Azure

Le moyen le plus simple de créer votre premier compte de stockage Azure est d’utiliser le portail Azure. Pour plus d’informations, consultez la page Créer un compte de stockage.

Vous pouvez également créer un compte de stockage Azure à l’aide d’Azure PowerShell, de l’interface de ligne de commande Azure ou du fournisseur de ressources de stockage Azure pour .NET.

Si vous préférez ne pas créer de compte de stockage dans Azure pour le moment, vous avez la possibilité d’utiliser l’émulateur de stockage Azure pour exécuter et tester votre code dans un environnement local. Pour plus d’informations, consultez Utiliser l’émulateur Azurite à des fins de développement local pour Stockage Azure.

Configurer l''environnement de développement

Ensuite, configurez votre environnement de développement dans Visual Studio afin d’être prêt pour essayer les exemples de code fournis dans ce guide.

Créer un projet d’application de console Windows

Dans Visual Studio, créez une application de console Windows. Les étapes suivantes vous montrent comment créer une application console dans Visual Studio 2019. Les étapes sont semblables pour d’autres versions de Visual Studio.

  1. Sélectionnez Fichier>Nouveau>Projet
  2. Sélectionnez Plateforme>Windows
  3. Sélectionnez Application console (.NET Framework)
  4. Sélectionnez Suivant.
  5. Saisissez un nom pour votre application dans le champ Nom du projet.
  6. Sélectionnez Créer

Tous les exemples de code figurant dans ce didacticiel peuvent être ajoutés à la méthode Main() du fichier Program.cs de votre application de console.

Vous pouvez utiliser les bibliothèques de client du Stockage Azure dans n’importe quelle application .NET, y compris un service cloud Azure, une application web, ou une application de bureau ou mobile. Dans ce guide, nous utilisons une application console pour plus de simplicité.

Utiliser NuGet pour installer les packages requis

Pour terminer ce didacticiel, vous devez référencer les quatre packages suivants dans votre projet :

Vous pouvez utiliser NuGet pour obtenir ces packages. Procédez comme suit :

  1. Cliquez avec le bouton droit sur votre projet dans l’Explorateur de solutions, puis sélectionnez Gérer les packages NuGet.
  2. Sélectionnez Parcourir.
  3. Recherchez Azure.Storage.Queues sur Internet, puis sélectionnez Installer pour installer la bibliothèque de client Stockage Azure et ses dépendances. Cela aura également pour effet d’installer les bibliothèques Azure.Storage.Common et Azure.Core, qui sont des dépendances de la bibliothèque de file d’attente.
  4. Recherchez System.Configuration.ConfigurationManager sur Internet, puis sélectionnez Installer pour installer Configuration Manager.

Déterminer votre environnement cible

Vous avez le choix entre deux environnements pour exécuter les exemples de ce guide :

  • Vous pouvez exécuter votre code sur un compte Azure Storage dans le cloud.
  • Vous pouvez exécuter votre code sur l’émulateur de stockage Azurite. L’émulateur de stockage Azurite est un environnement local qui émule un compte Stockage Azure dans le cloud. Azurite est une option gratuite permettant de tester et déboguer votre code lors du développement de votre application. L’émulateur utilise un compte et une clé connus. Pour plus d’informations, consultez Utilisation de l’émulateur Azurite pour le développement et le test de Stockage Azure local.

Notes

Vous pouvez cibler l’émulateur de stockage pour éviter les frais liés à l’utilisation des services de stockage Azure. Toutefois, si vous choisissez de cibler un compte de stockage Azure situé dans le cloud, les frais associés à l’utilisation de ce tutoriel seront négligeables.

Obtenir votre chaîne de connexion de stockage

Les bibliothèques de client du Stockage Azure pour .NET prennent en charge l’utilisation d’une chaîne de connexion de stockage pour la configuration de points de terminaison et d’informations d’identification permettant d’accéder aux services de stockage. Pour plus d’informations, consultez Gérer les clés d’accès au compte de stockage.

Copier vos informations d’identification depuis le portail Azure

L’exemple de code a besoin d’autoriser l’accès à votre compte de stockage. Pour l’autorisation, vous devez fournir vos informations d’identification du compte de stockage à l’application sous la forme d’une chaîne de connexion. Pour afficher les informations d’identification de votre compte de stockage :

  1. Accédez au portail Azure.

  2. Recherchez votre compte de stockage.

  3. Dans la section Paramètres de la présentation du compte de stockage, sélectionnez Clés d’accès. Vos clés d’accès au compte s’affichent, ainsi que la chaîne de connexion complète de chaque clé.

  4. Recherchez la valeur de Chaîne de connexion sous clé1, puis cliquez sur le bouton Copier pour copier la chaîne de connexion. Vous allez ajouter la valeur de chaîne de connexion dans une variable d’environnement à l’étape suivante.

    Screenshot showing how to copy a connection string from the Azure portal

Pour plus d’informations sur les chaînes de connexion, voir Configuration d’une chaîne de connexion dans Stockage Azure.

Notes

Votre clé de compte de stockage est similaire au mot de passe racine pour votre compte de stockage. Veillez toujours à protéger votre clé de compte de stockage. Évitez de la communiquer à d’autres utilisateurs, de la coder en dur ou de l’enregistrer dans un fichier texte brut accessible à d’autres personnes. Régénérez votre clé à l’aide du portail Azure si vous pensez que sa confidentialité est compromise.

La meilleure façon de conserver votre chaîne de connexion de stockage est dans un fichier de configuration. Pour configurer votre chaîne de connexion, ouvrez le fichier app.config depuis l’Explorateur de solutions dans Visual Studio. Ajoutez le contenu de l’élément <appSettings> indiqué ici. Remplacez connection-string par la valeur copiée depuis votre compte de stockage dans le portail :

<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <appSettings>
        <add key="StorageConnectionString" value="connection-string" />
    </appSettings>
</configuration>

Par exemple, votre paramètre de configuration est semblable à :

<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=GMuzNHjlB3S9itqZJHHCnRkrokLkcSyW7yK9BRbGp0ENePunLPwBgpxV1Z/pVo9zpem/2xSHXkMqTHHLcx8XRA==EndpointSuffix=core.windows.net" />

Pour cibler l’émulateur de stockage Azurite, vous pouvez utiliser un raccourci qui correspond à la clé et au nom de compte connus. Dans ce cas, le paramètre de votre chaîne de connexion est :

<add key="StorageConnectionString" value="UseDevelopmentStorage=true" />

Ajouter des directives d’utilisation

Ajoutez les directives using suivantes au fichier Program.cs :

using System; // Namespace for Console output
using System.Configuration; // Namespace for ConfigurationManager
using System.Threading.Tasks; // Namespace for Task
using Azure.Identity;
using Azure.Storage.Queues; // Namespace for Queue storage types
using Azure.Storage.Queues.Models; // Namespace for PeekedMessage

Créer le client du Stockage File d’attente

La classe QueueClient vous permet de récupérer des files d’attente stockées dans Stockage File d’attente. Voici un moyen de créer le client du service :

//-------------------------------------------------
// Create the queue service client
//-------------------------------------------------
public void CreateQueueClient(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to create and manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);
}

Vous êtes maintenant prêt à écrire du code qui lit et écrit des données dans le Stockage File d’attente.

Créer une file d’attente

Cet exemple montre comment créer une file d’attente :

//-------------------------------------------------
// Create a message queue
//-------------------------------------------------
public bool CreateQueue(string queueName)
{
    try
    {
        // Get the connection string from app settings
        string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

        // Instantiate a QueueClient which will be used to create and manipulate the queue
        QueueClient queueClient = new QueueClient(connectionString, queueName);

        // Create the queue
        queueClient.CreateIfNotExists();

        if (queueClient.Exists())
        {
            Console.WriteLine($"Queue created: '{queueClient.Name}'");
            return true;
        }
        else
        {
            Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}\n\n");
        Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
        return false;
    }
}

Insertion d'un message dans une file d'attente

Pour insérer un message dans une file d'attente existante, appelez la méthode SendMessage. Un message peut être une chaîne (au format UTF-8) ou un tableau d'octets. Le code suivant crée une file d’attente (si elle n’existe pas) et insère un message :

//-------------------------------------------------
// Insert a message into a queue
//-------------------------------------------------
public void InsertMessage(string queueName, string message)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to create and manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    // Create the queue if it doesn't already exist
    queueClient.CreateIfNotExists();

    if (queueClient.Exists())
    {
        // Send a message to the queue
        queueClient.SendMessage(message);
    }

    Console.WriteLine($"Inserted: {message}");
}

Lecture furtive du message suivant

Vous pouvez lire furtivement le message dans la file d’attente sans l’enlever de la file d’attente en appelant la méthode PeekMessages. Si vous ne transmettez pas de valeur pour le paramètre maxMessages, la valeur par défaut consiste à afficher un aperçu d’un message.

//-------------------------------------------------
// Peek at a message in the queue
//-------------------------------------------------
public void PeekMessage(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    { 
        // Peek at the next message
        PeekedMessage[] peekedMessage = queueClient.PeekMessages();

        // Display the message
        Console.WriteLine($"Peeked message: '{peekedMessage[0].Body}'");
    }
}

Modification du contenu d'un message en file d'attente

Vous pouvez modifier le contenu d'un message placé dans la file d'attente. Si le message représente une tâche, vous pouvez utiliser cette fonctionnalité pour mettre à jour l'état de la tâche. Le code suivant met à jour le message de la file d'attente avec un nouveau contenu et ajoute 60 secondes au délai d'expiration de la visibilité. Cette opération enregistre l'état de la tâche associée au message et accorde une minute supplémentaire au client pour traiter le message. Vous pouvez utiliser cette technique pour suivre des workflows à plusieurs étapes sur les messages de file d’attente, sans devoir reprendre du début si une étape du traitement échoue à cause d’une défaillance matérielle ou logicielle. Normalement, vous conservez aussi un nombre de nouvelles tentatives et si le message est retenté plus de n fois, vous le supprimez. Cela protège du déclenchement d'une erreur d'application par un message chaque fois qu'il est traité.

//-------------------------------------------------
// Update an existing message in the queue
//-------------------------------------------------
public void UpdateMessage(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Get the message from the queue
        QueueMessage[] message = queueClient.ReceiveMessages();

        // Update the message contents
        queueClient.UpdateMessage(message[0].MessageId, 
                message[0].PopReceipt, 
                "Updated contents",
                TimeSpan.FromSeconds(60.0)  // Make it invisible for another 60 seconds
            );
    }
}

Suppression du message suivant de la file d’attente

Supprimez un message d’une file d’attente en deux étapes. Lorsque vous appelez ReceiveMessages, vous obtenez le message suivant dans une file d'attente. Un message renvoyé par ReceiveMessages devient invisible par les autres codes lisant les messages de cette file d'attente. Par défaut, ce message reste invisible pendant 30 secondes. Pour finaliser la suppression du message de la file d’attente, vous devez aussi appeler DeleteMessage. Ce processus de suppression d'un message en deux étapes garantit que, si votre code ne parvient pas à traiter un message à cause d'une défaillance matérielle ou logicielle, une autre instance de votre code peut obtenir le même message et réessayer. Votre code appelle DeleteMessage juste après le traitement du message.

//-------------------------------------------------
// Process and remove a message from the queue
//-------------------------------------------------
public void DequeueMessage(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Get the next message
        QueueMessage[] retrievedMessage = queueClient.ReceiveMessages();

        // Process (i.e. print) the message in less than 30 seconds
        Console.WriteLine($"Dequeued message: '{retrievedMessage[0].Body}'");

        // Delete the message
        queueClient.DeleteMessage(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
    }
}

Utiliser le modèle Async-Await avec les API Stockage File d’attente communes

Cet exemple décrit comment utiliser le modèle Async-Await avec les API Stockage File d’attente communes. L’exemple appelle la version asynchrone de chacune des méthodes spécifiées, comme l’indique le suffixe Async de chaque méthode. Quand une méthode asynchrone est utilisée, le modèle Async-Await suspend l’exécution locale jusqu’à la fin de l’appel. Ce comportement permet au thread actuel d’effectuer d’autres tâches afin d’éviter les goulots d’étranglement au niveau des performances et d’améliorer la réactivité globale de votre application. Pour plus d’informations sur l’utilisation du modèle Async-Await dans .NET, consultez l’article Async et Await (C# et Visual Basic)

//-------------------------------------------------
// Perform queue operations asynchronously
//-------------------------------------------------
public async Task QueueAsync(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    // Create the queue if it doesn't already exist
    await queueClient.CreateIfNotExistsAsync();

    if (await queueClient.ExistsAsync())
    {
        Console.WriteLine($"Queue '{queueClient.Name}' created");
    }
    else
    {
        Console.WriteLine($"Queue '{queueClient.Name}' exists");
    }

    // Async enqueue the message
    await queueClient.SendMessageAsync("Hello, World");
    Console.WriteLine($"Message added");

    // Async receive the message
    QueueMessage[] retrievedMessage = await queueClient.ReceiveMessagesAsync();
    Console.WriteLine($"Retrieved message with content '{retrievedMessage[0].Body}'");

    // Async delete the message
    await queueClient.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
    Console.WriteLine($"Deleted message: '{retrievedMessage[0].Body}'");

    // Async delete the queue
    await queueClient.DeleteAsync();
    Console.WriteLine($"Deleted queue: '{queueClient.Name}'");
}

Utiliser des options supplémentaires pour retirer des messages de la file d’attente

Il existe deux façons de personnaliser la récupération des messages à partir d'une file d'attente. Premièrement, vous pouvez obtenir un lot de messages (jusqu'à 32). Deuxièmement, vous pouvez définir un délai d'expiration de l'invisibilité plus long ou plus court afin d'accorder à votre code plus ou moins de temps pour traiter complètement chaque message.

L'exemple de code suivant utilise la méthode ReceiveMessages pour obtenir 20 messages en un appel. Ensuite, il traite chaque message à l'aide d'une boucle foreach. Il définit également le délai d'expiration de l'invisibilité sur cinq minutes pour chaque message. Notez que le délai de 5 minutes démarre en même temps pour tous les messages. Par conséquent, une fois les 5 minutes écoulées après l’appel de ReceiveMessages, tous les messages n’ayant pas été supprimés redeviennent visibles.

//-----------------------------------------------------
// Process and remove multiple messages from the queue
//-----------------------------------------------------
public void DequeueMessages(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Receive and process 20 messages
        QueueMessage[] receivedMessages = queueClient.ReceiveMessages(20, TimeSpan.FromMinutes(5));

        foreach (QueueMessage message in receivedMessages)
        {
            // Process (i.e. print) the messages in less than 5 minutes
            Console.WriteLine($"De-queued message: '{message.Body}'");

            // Delete the message
            queueClient.DeleteMessage(message.MessageId, message.PopReceipt);
        }
    }
}

Obtention de la longueur de la file d'attente

Vous pouvez obtenir une estimation du nombre de messages dans une file d'attente. La méthode GetProperties retourne les propriétés de file d’attente, y compris le nombre de messages. La propriété ApproximateMessagesCount contient le nombre approximatif de messages dans la file d’attente. Ce nombre n’est pas inférieur au nombre réel de messages dans la file d’attente, mais peut être supérieur.

//-----------------------------------------------------
// Get the approximate number of messages in the queue
//-----------------------------------------------------
public void GetQueueLength(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        QueueProperties properties = queueClient.GetProperties();

        // Retrieve the cached approximate message count.
        int cachedMessagesCount = properties.ApproximateMessagesCount;

        // Display number of messages.
        Console.WriteLine($"Number of messages in queue: {cachedMessagesCount}");
    }
}

Suppression d'une file d'attente

Pour supprimer une file d'attente et tous les messages qu'elle contient, appelez la méthode Delete sur l'objet file d'attente.

//-------------------------------------------------
// Delete the queue
//-------------------------------------------------
public void DeleteQueue(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Delete the queue
        queueClient.Delete();
    }

    Console.WriteLine($"Queue deleted: '{queueClient.Name}'");
}

Étapes suivantes

Maintenant que vous connaissez les bases du stockage file d’attente, consultez les liens suivants pour apprendre à exécuter les tâches de stockage plus complexes.