Поделиться через


Руководство: Работа с очередями в хранилище очередей Azure в .NET

Хранилище очередей Azure реализует облачный механизм очередей для поддержки взаимодействия между компонентами распределенного приложения. Каждая очередь ведет список сообщений, которые могут быть добавлены компонентом отправителя и обработаны компонентом получателя. Использование очереди позволяет вашему приложению сразу же масштабироваться для удовлетворения спроса. В этой статье показаны основные шаги для работы с очередью Azure Queue Storage.

В этом руководстве описано следующее:

  • Создание учетной записи хранения Azure
  • Создание приложения
  • Добавление клиентских библиотек Azure
  • Добавить поддержку для асинхронного кода
  • Создать очередь
  • Вставка сообщения в очередь
  • Вывод сообщений из очереди
  • Удаление пустой очереди
  • Проверка аргументов командной строки
  • Сборка и запуск приложения

Предварительные условия

Создание учетной записи хранения Azure

  1. Прежде всего создайте учетную запись хранения Azure.

    Пошаговые инструкции по созданию учетной записи хранения см. в статье Создание учетной записи хранения. Это отдельный шаг, который вы выполняете после создания бесплатной учетной записи Azure для выполнения предварительных требований.

  2. Убедитесь, что вашей учетной записи пользователя назначена роль участника данных очереди хранилища в рамках учетной записи хранения, родительской группы ресурсов или подписки. Смотрите авторизацию в Azure.

Создание приложения

Создайте приложение .NET Core с именем QueueApp. Для простоты это приложение будет одновременно отправлять и принимать сообщения через очередь.

  1. В окне консоли (cmd, PowerShell или Azure CLI) выполните команду dotnet new, чтобы создать консольное приложение с именем QueueApp. Эта команда создает простой проект Hello World на языке C# с одним файлом исходного кода: Program.cs.

    dotnet new console -n QueueApp
    
  2. Перейдите в созданную папку QueueApp и создайте приложение, чтобы убедиться, что все в порядке.

    cd QueueApp
    
    dotnet build
    

    Должен отобразиться похожий результат:

    C:\Tutorials>dotnet new console -n QueueApp
    The template "Console Application" was created successfully.
    
    Processing post-creation actions...
    Running 'dotnet restore' on QueueApp\QueueApp.csproj...
      Restore completed in 155.63 ms for C:\Tutorials\QueueApp\QueueApp.csproj.
    
    Restore succeeded.
    
    C:\Tutorials>cd QueueApp
    
    C:\Tutorials\QueueApp>dotnet build
    Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
    Copyright (C) Microsoft Corporation. All rights reserved.
    
      Restore completed in 40.87 ms for C:\Tutorials\QueueApp\QueueApp.csproj.
      QueueApp -> C:\Tutorials\QueueApp\bin\Debug\netcoreapp3.1\QueueApp.dll
    
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:02.40
    
    C:\Tutorials\QueueApp>_
    

Добавление клиентских библиотек Azure

  1. Добавьте клиентские библиотеки службы хранилища Azure в проект с помощью команды dotnet add package.

    Выполните следующую команду из папки проекта в окне консоли.

    dotnet add package Azure.Storage.Queues
    

Добавьте инструкции using

  1. Перейдите в каталог проекта и введите в командной строке code ., чтобы открыть Visual Studio Code в этом каталоге. Оставьте окно командной строки открытым. Позднее нужно будет выполнить больше команд. Если появится предложение добавить необходимые для сборки и отладки ресурсы C#, нажмите кнопку Да.

  2. Откройте файл исходного кода Program.cs и добавьте следующие пространства имен сразу за инструкцией using System;. Это приложение использует типы из этих пространств имен, чтобы подключаться к Azure Storage и работать с очередями.

    using System.Threading.Tasks;
    using Azure.Storage.Queues;
    using Azure.Storage.Queues.Models;
    
  3. Сохраните файл Program.cs.

Добавление поддержки для асинхронного кода

Так как приложение использует облачные ресурсы, код выполняется асинхронно.

  1. Обновите метод Main, чтобы он выполнялся асинхронно. Замените void возвращаемым значением async Task.

    static async Task Main(string[] args)
    
  2. Сохраните файл Program.cs.

Создать очередь

Прежде чем выполнять вызовы в API Azure, необходимо убедиться, что вы прошли аутентификацию с той учетной записью Microsoft Entra, которой назначена роль. После проверки подлинности можно создать и авторизовать QueueClient объект, используя DefaultAzureCredential, для доступа к данным очереди в учетной записи хранения. DefaultAzureCredential автоматически обнаруживает и использует учетную запись, в которую вы вошли. Сведения о входе и создании QueueClient объекта см. в статье "Авторизация доступа" и создание клиентского объекта.

Вставка сообщения в очередь

Создайте новый метод для отправки сообщения в очередь.

  1. Добавьте в класс InsertMessageAsync следующий метод Program.

    Этому методу передается ссылка на очередь. Если очередь не существует, она создается при вызове CreateIfNotExistsAsync. Затем оно добавляет newMessage в очередь, вызывая SendMessageAsync.

    static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
    {
        if (null != await theQueue.CreateIfNotExistsAsync())
        {
            Console.WriteLine("The queue was created.");
        }
    
        await theQueue.SendMessageAsync(newMessage);
    }
    
  2. Необязательно. По умолчанию максимальное время хранения сообщения составляет 7 дней. Для срока жизни сообщения можно указать любое положительное число. В следующем фрагменте кода добавляется сообщение, для которого срок действия никогда не истекает.

    Чтобы добавить сообщение с неограниченным сроком действия, используйте Timespan.FromSeconds(-1) при вызове SendMessageAsync.

    await theQueue.SendMessageAsync(newMessage, default, TimeSpan.FromSeconds(-1), default);
    
  3. Сохраните файл.

Сообщение очереди должно иметь формат, совместимый с XML-запросом в кодировке UTF-8. Размер сообщения может достигать 64 КБ. Если сообщение содержит двоичные данные, примените к нему кодировку Base64.

Вывод сообщений из очереди

Создайте новый метод для получения сообщения из очереди. Очень важно удалять из очереди успешно полученные сообщения, чтобы они не обрабатывались более одного раза.

  1. Добавьте новый метод с именем RetrieveNextMessageAsync в класс Program.

    Этот метод получает сообщение из очереди, вызывая ReceiveMessagesAsync с параметром 1 в первом аргументе, чтобы извлечь только следующее сообщение из очереди. Получив сообщение, удалите его из очереди с помощью метода DeleteMessageAsync.

    Когда сообщение отправляется в очередь с помощью пакета SDK до версии 12, оно автоматически кодируется в Base64. Начиная с версии 12, эта функциональность была удалена. При извлечении сообщения при помощи SDK v12, оно не декодируется автоматически из Base64. Вы должны самостоятельно декодировать содержимое из Base64.

    static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
    {
        if (await theQueue.ExistsAsync())
        {
            QueueProperties properties = await theQueue.GetPropertiesAsync();
    
            if (properties.ApproximateMessagesCount > 0)
            {
                QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                string theMessage = retrievedMessage[0].Body.ToString();
                await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                return theMessage;
            }
    
            return null;
        }
    
        return null;
    }
    
  2. Сохраните файл.

Удаление пустой очереди

По завершении работы с проектом мы рекомендуем всегда оценивать, нужны ли вам созданные ресурсы. Ресурсы, которые остаются включенными, могут обойтись вам в деньги. Если очередь существует, но пуста, предложите пользователю удалить ее.

  1. Расширьте метод RetrieveNextMessageAsync, добавив запрос на удаление пустой очереди.

    static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
    {
        if (await theQueue.ExistsAsync())
        {
            QueueProperties properties = await theQueue.GetPropertiesAsync();
    
            if (properties.ApproximateMessagesCount > 0)
            {
                QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                string theMessage = retrievedMessage[0].Body.ToString();
                await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                return theMessage;
            }
            else
            {
                Console.Write("The queue is empty. Attempt to delete it? (Y/N) ");
                string response = Console.ReadLine();
    
                if (response.ToUpper() == "Y")
                {
                    await theQueue.DeleteIfExistsAsync();
                    return "The queue was deleted.";
                }
                else
                {
                    return "The queue was not deleted.";
                }
            }
        }
        else
        {
            return "The queue does not exist. Add a message to the command line to create the queue and store the message.";
        }
    }
    
  2. Сохраните файл.

Проверка аргументов командной строки

Если в приложение переданы аргументы командной строки, мы будем считать их сообщением для добавления в очередь. Объедините эти аргументы в одну строку. Добавьте эту строку в очередь сообщений, вызвав добавленный ранее метод InsertMessageAsync.

Если в командной строке нет аргументов, выполните попытку извлечения. Вызовите метод RetrieveNextMessageAsync для получения следующего сообщения из очереди.

Дождитесь ввода пользователя, а затем вызовите Console.ReadLine для завершения работы.

  1. Дополните метод Main проверкой аргументов командной строки и ожиданием действий пользователя. В приведенном ниже фрагменте кода необходимо заменить метку позиции {storageAccountName} именем вашей учетной записи хранения.

    static async Task Main(string[] args)
    {
       QueueClient queue = new QueueClient(
          new Uri($"https://{storageAccountName}.queue.core.windows.net/mystoragequeue"),
          new DefaultAzureCredential());
    
       if (args.Length > 0)
       {
          string value = String.Join(" ", args);
          await InsertMessageAsync(queue, value);
          Console.WriteLine($"Sent: {value}");
       }
       else
       {
          string value = await RetrieveNextMessageAsync(queue);
          Console.WriteLine($"Received: {value}");
       }
    
       Console.Write("Press Enter...");
       Console.ReadLine();
    }
    
  2. Сохраните файл.

Полный код

Ниже приведен полный код для этого проекта.

using System;
using System.Threading.Tasks;
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;
using Azure.Identity;

namespace QueueApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            QueueClient queue = new QueueClient(
               new Uri($"https://{storageAccountName}.queue.core.windows.net/mystoragequeue"),
               new DefaultAzureCredential());

            if (args.Length > 0)
            {
                string value = String.Join(" ", args);
                await InsertMessageAsync(queue, value);
                Console.WriteLine($"Sent: {value}");
            }
            else
            {
                string value = await RetrieveNextMessageAsync(queue);
                Console.WriteLine($"Received: {value}");
            }

            Console.Write("Press Enter...");
            Console.ReadLine();
        }

        static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
        {
            if (null != await theQueue.CreateIfNotExistsAsync())
            {
                Console.WriteLine("The queue was created.");
            }

            await theQueue.SendMessageAsync(newMessage);
        }

        static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
        {
            if (await theQueue.ExistsAsync())
            {
                QueueProperties properties = await theQueue.GetPropertiesAsync();

                if (properties.ApproximateMessagesCount > 0)
                {
                    QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                    string theMessage = retrievedMessage[0].Body.ToString();
                    await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                    return theMessage;
                }
                else
                {
                    Console.Write("The queue is empty. Attempt to delete it? (Y/N) ");
                    string response = Console.ReadLine();

                    if (response.ToUpper() == "Y")
                    {
                        await theQueue.DeleteIfExistsAsync();
                        return "The queue was deleted.";
                    }
                    else
                    {
                        return "The queue was not deleted.";
                    }
                }
            }
            else
            {
                return "The queue does not exist. Add a message to the command line to create the queue and store the message.";
            }
        }
    }
}

Сборка и запуск приложения

  1. В командной строке в каталоге проекта выполните следующую команду dotnet, чтобы скомпилировать проект.

    dotnet build
    
  2. Когда сборка проекта успешно завершится, выполните следующую команду для добавления первого сообщения в очередь.

    dotnet run First queue message
    

    Вы должны увидеть следующий результат:

    C:\Tutorials\QueueApp>dotnet run First queue message
    The queue was created.
    Sent: First queue message
    Press Enter..._
    
  3. Запустите приложение без аргументов командной строки, чтобы получить и удалить первое сообщение из очереди.

    dotnet run
    
  4. Продолжайте запускать приложение, пока все сообщения не будут удалены. При следующем запуске вы получите сообщение о том, что очередь пуста, и запрос на ее удаление.

    C:\Tutorials\QueueApp>dotnet run First queue message
    The queue was created.
    Sent: First queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run Second queue message
    Sent: Second queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run Third queue message
    Sent: Third queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: First queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: Second queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: Third queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    The queue is empty. Attempt to delete it? (Y/N) Y
    Received: The queue was deleted.
    Press Enter...
    
    C:\Tutorials\QueueApp>_
    

Следующие шаги

Из этого руководства вы узнали, как:

  1. Создать очередь
  2. Добавление и удаление сообщений из очереди
  3. Удалите очередь в Хранилище очередей Azure

Изучите руководства по быстрому началу работы для Хранилища очередей Azure, чтобы узнать больше.

Дополнительные примеры кода, использующие устаревшие пакеты SDK для .NET версии 11.x, см. в примерах кода с помощью .NET версии 11.x.