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


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

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

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

  • Создание учетной записи хранения 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 и работать с очередями.

    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. Добавьте в класс Program следующий метод InsertMessageAsync.

    Этому методу передается ссылка на очередь. Если очередь не существует, она создается при вызове 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 версии 12 оно не декодируется автоматически. Необходимо явным образом выполнить для содержимого декодирование из 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.