Delen via


Aan de slag met Azure Queue Storage met .NET

Overzicht

Azure Queue Storage biedt cloudberichten tussen toepassingsonderdelen. Bij het ontwerpen van toepassingen voor schaal worden toepassingsonderdelen vaak losgekoppeld, zodat ze onafhankelijk 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 biedt ook ondersteuning voor het beheren van asynchrone taken en het bouwen van proceswerkstromen.

Over deze zelfstudie

Deze zelfstudie laat zien hoe u .NET-code schrijft voor enkele 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 van werk te maken die asynchroon moet worden verwerkt.

Concepten van Queue-service

De Azure Queue-service bevat de volgende onderdelen:

Onderdelen van de Azure Queue-service

  • Opslagaccount: Alle toegang tot Azure Storage wordt uitgevoerd via een opslagaccount. 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: Wachtrijen kunnen worden adresseerbaar met 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-opslagaccount 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 opslagaccount in Azure maakt, kunt u de Azurite-opslagemulator ook gebruiken om uw code uit te voeren en te testen in een lokale omgeving. Zie Use the Azurite emulator for local Azure Storage development (De Azurite-emulator gebruiken voor lokale Azure Storage-ontwikkeling) voor meer informatie.

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>Nieuw>project
  2. Platform windows>selecteren
  3. Console-app selecteren (.NET Framework)
  4. Selecteer Volgende
  5. Voer in het veld Projectnaam 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 Azure Storage-clientbibliotheken gebruiken in elk type .NET-toepassing, waaronder een Azure-cloudservice of web-app, en desktop- 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.Queuesen selecteer Installeren om de Azure Storage-clientbibliotheek en de bijbehorende afhankelijkheden te installeren. Hiermee worden ook de bibliotheken Azure.Storage.Common en Azure.Core geïnstalleerd. Dit zijn afhankelijkheden van de wachtrijbibliotheek.
  4. Zoek online naar System.Configuration.ConfigurationManageren selecteer Installeren om de Configuration Manager te installeren.

De doelomgeving bepalen

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

Notitie

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

Uw connection string voor opslag ophalen

De Azure Storage-clientbibliotheken voor .NET ondersteunen het gebruik van een opslag-connection string voor het configureren van eindpunten en referenties 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 toe van het <appSettings> element dat hier wordt weergegeven. Vervang door connection-string 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 toegewezen 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 de QueueClient 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);
}

Tip

Berichten die u verzendt met behulp van de QueueClient klasse, moeten een indeling hebben die kan worden opgenomen in een XML-aanvraag met UTF-8-codering. Desgewenst kunt u de optie MessageEncoding instellen op Base64 om niet-compatibele berichten te verwerken.

U bent nu klaar om code te schrijven waarmee gegevens worden gelezen uit en naar Queue Storage worden geschreven.

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 in een bestaande wachtrij wilt invoegen, roept u de methode aan SendMessage . Een bericht kan een tekenreeks (in UTF-8-indeling) of een bytematrix zijn. Met de volgende code wordt een wachtrij gemaakt (als deze nog niet bestaat) en wordt een bericht ingevoegd:

//-------------------------------------------------
// 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 PeekMessages methode aan te roepen. Als u geen waarde doorgeeft voor de maxMessages parameter, is de standaardinstelling 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 opnieuw hoeft te beginnen als een verwerkingsstap mislukt vanwege hardware- of softwarefouten. 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 wachtrij verwijderen

Een bericht uit een wachtrij verwijderen in twee stappen. Wanneer u aanroept ReceiveMessages, krijgt u het volgende bericht in een wachtrij. Een bericht dat wordt geretourneerd van ReceiveMessages , wordt onzichtbaar voor andere code die berichten uit deze wachtrij leest. Standaard blijft het bericht onzichtbaar gedurende 30 seconden. Als u het verwijderen van het bericht uit de wachtrij wilt voltooien, moet u ook aanroepen DeleteMessage. 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 gebruiken met algemene Queue Storage-API's

In dit voorbeeld ziet u hoe u het patroon Async-Await gebruikt met algemene Queue Storage-API's. In het voorbeeld wordt de asynchrone versie van elk van de opgegeven methoden aangeroepen, zoals wordt aangegeven door het Async achtervoegsel van elke methode. Wanneer een asynchrone methode wordt gebruikt, onderbreekt het patroon Async-Await lokale uitvoering 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 en Await (C# en Visual Basic) voor meer informatie over het gebruik van het patroon Async-Await 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}'");
}

Extra opties gebruiken voor het verwijderen 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 worden gestart, dus nadat er vijf minuten zijn verstreken sinds de aanroep naar ReceiveMessages, worden alle berichten die niet zijn verwijderd, weer 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, waaronder 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.

Zie Codevoorbeelden met .NET versie 11.x voor gerelateerde codevoorbeelden met behulp van afgeschafte .NET versie 11.x SDK's.