Aan de slag met Azure Queue Storage met .NET

Overzicht

Azure Queue Storage biedt cloudberichten tussen toepassingsonderdelen. Bij het ontwerpen van schaaltoepassingen worden toepassingsonderdelen vaak losgekoppeld, zodat ze onafhankelijk van elkaar kunnen worden geschaald. Queue Storage biedt asynchrone berichten tussen toepassingsonderdelen, ongeacht of deze worden uitgevoerd in de cloud, op het bureaublad, op een on-premises server of op een mobiel apparaat. Queue Storage ook het beheren van asynchrone taken en het bouwen van proceswerkstromen.

Over deze zelfstudie

Deze zelfstudie laat zien hoe u .NET-code schrijft voor een aantal veelvoorkomende scenario's met behulp van Azure Queue Storage. Scenario's die aan bod komen, zijn onder meer het maken en verwijderen van wachtrijen en het toevoegen, lezen en verwijderen van wachtrijberichten.

Geschatte duur: 45 minuten

Vereisten

Wat is Queue Storage?

Azure Queue Storage is een service voor de opslag van grote aantallen berichten die via HTTP of HTTPS overal vandaan kunnen worden opgevraagd met geverifieerde aanroepen. Een enkel wachtrijbericht mag maximaal 64 KB groot zijn en een wachtrij kan miljoenen berichten bevatten, tot de totale capaciteitslimiet van een opslagaccount. Queue Storage wordt vaak gebruikt om een achterstand te maken voor het asynchroon verwerken van werk.

Concepten van Queue-service

De Azure Queue-service bevat de volgende onderdelen:

Azure Queue-service-onderdelen

  • Opslag account: Alle toegang tot Azure Storage wordt uitgevoerd via een opslag account. Zie Overzicht van opslagaccount voor meer informatie over opslagaccounts.

  • Wachtrij: Een wachtrij bevat een set berichten. Alle berichten moeten zich in een wachtrij bevinden. De naam van een wachtrij mag alleen kleine letters bevatten. Zie Naming Queues and Metadata (Wachtrijen en metagegevens een naam geven) voor informatie over de naamgeving van wachtrijen.

  • Bericht: Een bericht in een willekeurige indeling, van maximaal 64 KB. Een bericht kan maximaal 7 dagen in de wachtrij blijven staan. Voor versie 29-07-2017 of hoger mag de maximale time-to-live elk positief getal zijn. Of -1 om aan te geven dat het bericht niet verloopt. Als deze parameter wordt weggelaten, is de standaard time-to-live zeven dagen.

  • URL-indeling: Wacht rijen zijn adresseerbaar met behulp van de volgende URL-indeling: http:// <storage account> . Queue.core.Windows.net/<queue>

    Met de volgende URL wordt een wachtrij in het diagram opgevraagd:

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

Een Azure-opslagaccount maken

De eenvoudigste manier om uw eerste Azure-opslag account te maken, is met behulp van de Azure Portal. Zie Een opslagaccount maken voor meer informatie.

U kunt ook een Azure-opslagaccount maken met behulp van Azure PowerShell, Azure CLI of de Azure Storage Resource Provider voor .NET.

Als u op dit moment liever geen opslag account maakt in azure, kunt u ook de Azurite-opslag emulator gebruiken om uw code uit te voeren en te testen in een lokale omgeving. Zie voor meer informatie de Azurite-emulator gebruiken voor het ontwikkelen van lokale Azure Storage.

De ontwikkelomgeving instellen

Vervolgens stelt u in Visual Studio uw ontwikkelomgeving in, zodat u de codevoorbeelden in deze handleiding kunt uitproberen.

Een Windows-consoletoepassingsproject maken

Maak in Visual Studio een nieuwe Windows-consoletoepassing. In de volgende stappen ziet u hoe u een consoletoepassing maakt in Visual Studio 2019. De stappen zijn nagenoeg gelijk in andere versies van Visual Studio.

  1. Selecteer Bestand > Nieuwe > Project
  2. Selecteer Platform > Windows
  3. Selecteer Console-app (.NET Framework)
  4. Selecteer Volgende
  5. Voer in Project veld Naam een naam in voor uw toepassing
  6. Selecteer Maken

Alle codevoorbeelden in deze zelfstudie kunnen worden toegevoegd aan de methode Main() van het bestand Program.cs van de consoletoepassing.

U kunt de clientbibliotheken Azure Storage in elk type .NET-toepassing, waaronder een Azure-cloudservice of -web-app, en bureaublad- en mobiele toepassingen. In deze gids gebruiken we een consoletoepassing voor de eenvoud.

NuGet gebruiken om de vereiste pakketten te installeren

U moet verwijzen naar de volgende vier pakketten in uw project om deze zelfstudie te voltooien:

U kunt NuGet gebruiken om deze pakketten te verkrijgen. Volg deze stappen:

  1. Klik met de rechtermuisknop op uw project in Solution Explorer en kies NuGet-pakketten beheren.
  2. Bladeren selecteren
  3. Zoek online naar Azure.Storage.Queues en selecteer Installeren om de Azure Storage clientbibliotheek en de afhankelijkheden ervan te installeren. Hiermee wordt ook Azure geïnstalleerd. Storage. Algemene en Azure.Core-bibliotheken, die afhankelijkheden zijn van de wachtrijbibliotheek.
  4. Zoek online naar System.Configuration.ConfigurationManager en selecteer Installeren om de Configuration Manager.

De doelomgeving bepalen

U kunt de voorbeelden in deze gids in twee omgevingen uitvoeren:

  • U kunt de code uitvoeren met een Azure Storage-account in de cloud.
  • U kunt uw code uitvoeren op de Azurite-opslagemulator. Azurite is een lokale omgeving waarin een Azure Storage account in de cloud wordt geëmuleerd. Azurite is een gratis optie voor het testen en debuggen van uw code terwijl uw toepassing in ontwikkeling is. De emulator maakt gebruik van een bekend account en een bekende sleutel. Zie Use the Azurite emulator for local Azure Storage development and testing (De Azurite-emulatorgebruiken voor lokale Azure Storage ontwikkelen en testen) voor meer informatie.

Notitie

Gebruik de opslagemulator als u mogelijke kosten in verband met Azure-opslag wilt vermijden. Als u er echter voor kiest om een account Azure Storage in de cloud te gebruiken, zijn de kosten voor het uitvoeren van deze zelfstudie te laag.

Uw opslagopslag connection string

De Azure Storage voor .NET ondersteunen met behulp van een connection string eindpunten en referenties te configureren voor toegang tot opslagservices. Zie Toegangssleutels voor een opslagaccount beheren voor meer informatie.

Kopieer uw referenties van de Azure Portal

De voorbeeldcode moet de toegang tot uw opslagaccount autoriseren. Om te autoriseren geeft u de toepassing de referenties van uw opslagaccount in de vorm van een verbindingsreeks. Om uw opslagaccountreferenties te zien, doet u het volgende:

  1. Navigeer naar Azure Portal.

  2. Zoek uw opslagaccount.

  3. In de sectie Instellingen van het overzicht met opslagaccounts selecteert u Toegangssleutels. De toegangssleutels van uw account worden weergegeven, evenals de volledige verbindingsreeks voor elke sleutel.

  4. Zoek de waarde van de Verbindingsreeks onder key1 en klik op de knop Kopiëren om de verbindingsreeks te kopiëren. U gaat in de volgende stap de waarde voor de verbinding toevoegen aan een omgevingsvariabele.

    Schermopname waarin een verbindingsreeks vanuit de Azure-portal wordt gekopieerd

Zie Azure Storage-verbindingsreeksen configureren voor meer informatie over verbindingsreeksen.

Notitie

De sleutel van uw opslagaccount is vergelijkbaar met het hoofdwachtwoord voor uw opslagaccount. Zorg dat de sleutel van uw opslagaccount altijd is beveiligd. Geef deze niet aan andere gebruikers en bewaar of noteer de sleutel op een veilige manier en plaats. Genereer een nieuwe sleutel via de Azure-portal als er mogelijk inbreuk op de sleutel heeft plaatsgevonden.

De beste manier om de opslagverbindingsreeks te onderhouden, is met een configuratiebestand. U configureert de verbindingsreeks door het bestand app.config te openen vanuit Solution Explorer in Visual Studio. Voeg de inhoud van het <appSettings> element toe dat hier wordt weergegeven. Vervang connection-string door de waarde die u hebt gekopieerd uit uw opslagaccount in de portal:

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

De configuratie-instelling ziet er ongeveer als volgt uit:

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

Als u zich wilt richten op de Azurite-opslagemulator, kunt u een snelkoppeling gebruiken die wordt toegeschreven aan de bekende accountnaam en -sleutel. In dat geval heeft de verbindingsreeks de volgende instelling:

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

Using-instructies toevoegen

Voeg de volgende Program.cs-instructies aan het begin van het bestand using toe:

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

De Queue Storage-client maken

Met QueueClient de klasse kunt u wachtrijen ophalen die zijn opgeslagen in Queue Storage. Hier volgt één manier om de serviceclient te maken:

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

U bent nu klaar om code te schrijven die gegevens leest uit en schrijft naar Queue Storage.

Een wachtrij maken

In dit voorbeeld ziet u hoe u een wachtrij maakt:

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

Een bericht in een wachtrij invoegen

Als u een bericht wilt invoegen in een bestaande wachtrij, roept u de methode SendMessage aan. Een bericht kan een tekenreeks (in UTF-8-indeling) of een byte-matrix zijn. Met de volgende code maakt u een wachtrij (als deze nog niet bestaat) en voegt u een bericht in:

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

Bekijken van het volgende bericht

U kunt de berichten in de wachtrij bekijken zonder ze uit de wachtrij te verwijderen door de methode aan te PeekMessages roepen. Als u geen waarde voor de parameter doorgeeft, is de maxMessages standaardwaarde om één bericht te bekijken.

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

De inhoud van een bericht in de wachtrij wijzigen

U kunt de inhoud van een bericht in de wachtrij wijzigen. Als het bericht een werktaak vertegenwoordigt, kunt u deze functie gebruiken om de status van de werktaak bij te werken. Met de volgende code wordt het bericht in de wachtrij bijgewerkt met nieuwe inhoud en wordt de time-out voor de zichtbaarheid met 60 seconden verlengd. Hiermee wordt de status van de werkitems die aan het bericht zijn gekoppeld, opgeslagen en krijgt de client een extra minuut om aan het bericht te blijven werken. U kunt deze techniek gebruiken om werkstromen met meerdere stappen in wachtrijberichten bij te houden, zonder dat u vanaf het begin opnieuw moet beginnen als een verwerkingsstap mislukt vanwege een hardware- of softwarefout. Doorgaans houdt u ook het aantal nieuwe pogingen bij en als het bericht meer dan n keer opnieuw is geprobeerd, verwijdert u het. Dit biedt bescherming tegen berichten die een toepassingsfout activeren telkens wanneer ze worden verwerkt.

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

Het volgende bericht uit de verwijderd

U kunt in twee stappen een bericht uit een wachtrij uit de wachtrij in de wachtrij zetten. Wanneer u ReceiveMessages aanroept, krijgt u het volgende bericht in een wachtrij. Een bericht dat wordt geretourneerd ReceiveMessages door wordt onzichtbaar voor alle andere code die berichten uit deze wachtrij leest. Standaard blijft het bericht onzichtbaar gedurende 30 seconden. Als u het bericht uit de wachtrij wilt verwijderen, moet u ook DeleteMessage aanroepen. Dit proces in twee stappen voor het verwijderen van een bericht zorgt ervoor dat als de code er niet in slaagt een bericht te verwerken vanwege hardware- of softwareproblemen, een ander exemplaar van uw code hetzelfde bericht kan ophalen en het opnieuw kan proberen. Uw code roept aan DeleteMessage direct nadat het bericht is verwerkt.

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

Het patroon Async-Await met algemene Queue Storage-API's

In dit voorbeeld ziet u hoe u het patroon Async-Await met algemene Queue Storage API's. In het voorbeeld wordt de asynchrone versie van elk van de opgegeven methoden aanroepen, zoals aangegeven door het Async achtervoegsel van elke methode. Wanneer er een asyntische methode wordt gebruikt, Async-Await lokale uitvoering tijdelijk totdat de aanroep is voltooid. Dit gedrag stelt de huidige thread in staat andere bewerkingen uit te voeren, zodat knelpunten in de prestaties worden voorkomen en de algehele respons van uw toepassing verbetert. Zie Async and Await (C# en Visual Basic) voor meer informatie over het gebruik van het Async-Await-patroon in .NET.

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

Aanvullende opties gebruiken voor het uit dequequeneren van berichten

Er zijn twee manieren waarop u het ophalen van berichten uit een wachtrij kunt aanpassen. Ten eerste kunt u berichten batchgewijs (maximaal 32) ophalen. Ten tweede kunt u een langere of kortere time-out voor onzichtbaarheid instellen, zodat uw code meer of minder tijd krijgt voor het volledig verwerken van elk bericht.

In het volgende codevoorbeeld wordt de ReceiveMessages methode gebruikt om 20 berichten in één aanroep op te halen. Vervolgens wordt elk bericht verwerkt met behulp van een foreach lus. De time-out voor onzichtbaarheid wordt ingesteld op vijf minuten voor elk bericht. Houd er rekening mee dat de vijf minuten voor alle berichten tegelijk beginnen, dus nadat vijf minuten zijn verstreken sinds de aanroep van , worden berichten die niet zijn verwijderd, weer ReceiveMessages zichtbaar.

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

Lengte van de wachtrij ophalen

U kunt een schatting ophalen van het aantal berichten in de wachtrij. De GetProperties methode retourneert wachtrijeigenschappen, inclusief het aantal berichten. De ApproximateMessagesCount eigenschap bevat het geschatte aantal berichten in de wachtrij. Dit aantal is niet lager dan het werkelijke aantal berichten in de wachtrij, maar kan hoger zijn.

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

Een wachtrij verwijderen

Als u een wachtrij en alle berichten erin wilt verwijderen, roept u de Delete methode aan voor het wachtrijobject.

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

Volgende stappen

Nu u de basisbeginselen van Queue Storage hebt geleerd, volgt u deze koppelingen voor meer informatie over complexere opslagtaken.