チュートリアル:.NET で Azure Queue Storage キューを操作する

Azure Queue Storage では、クラウドベースのキューが実装され、分散アプリケーションのコンポーネント間で通信できます。 各キューには、送信側コンポーネントにより追加し、受信側コンポーネントにより処理できるメッセージの一覧が保持されます。 キューを利用することで、アプリケーションを需要に合わせてすぐにスケーリングできます。 この記事では、Azure Queue Storage を使用するための基本手順について説明します。

このチュートリアルでは、以下の内容を学習します。

  • Azure Storage アカウントの作成
  • アプリを作成する
  • Azure クライアント ライブラリを追加する
  • 非同期コードのサポートを追加する
  • キューを作成する
  • キューにメッセージを挿入する
  • メッセージをデキューする
  • 空のキューを削除する
  • コマンドライン引数を確認する
  • アプリのビルドと実行

前提条件

  • プラットフォームに依存しない Visual Studio Code エディターの無料コピーを入手します。
  • .NET Core SDK バージョン 3.1 以降をダウンロードし、インストールします。
  • Azure サブスクリプションを現在お持ちでない場合は、開始する前に無料アカウントを作成してください。

Azure Storage アカウントを作成する

まず、Azure Storage アカウントを作成します。 ストレージ アカウントを作成する詳細な手順については、「ストレージ アカウントを作成する」を参照してください。 前提条件の無料 Azure アカウントを作成した後に別途行う手順となります。

アプリを作成する

QueueApp という名前の .NET Core アプリケーションを作成します。 わかりやすくするために、このアプリではメッセージの送受信ともキューを介して行います。

  1. コンソール ウィンドウ (cmd、PowerShell、Azure CLI など) で、dotnet new コマンドを使用し、QueueApp という名前で新しいコンソール アプリを作成します。 このコマンドにより、1 つのソース ファイル (Program.cs) を使用する単純な "hello world" C# プロジェクトが作成されます。

    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. dotnet add package コマンドを使用して、Azure Storage クライアント ライブラリをプロジェクトに追加します。

    コンソール ウィンドウでプロジェクト フォルダーから次のコマンドを実行します。

    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 メソッドを更新します。 voidasync Task 戻り値に変更します。

    static async Task Main(string[] args)
    
  2. Program.cs ファイルを保存します。

キューを作成する

Azure API を呼び出す前に、Azure portal から資格情報を取得する必要があります。

Azure Portal で資格情報をコピーする

サンプル アプリケーションから Azure Storage に対して要求を実行するときは、承認されている必要があります。 要求を承認するには、ストレージ アカウントの資格情報を接続文字列としてアプリケーションに追加します。 ストレージ アカウントの資格情報を表示するには、次の手順に従います。

  1. Azure portal にサインインします。

  2. 自分のストレージ アカウントを探します。

  3. ストレージ アカウント メニュー ウィンドウの [セキュリティとネットワーク] で、 [アクセス キー] を選択します。 ここで、アカウント アクセス キーと各キーの完全な接続文字列が確認できます。

    Azure portal 内のアクセス キー設定の場所を示すスクリーンショット

  4. [アクセス キー] ペインで、 [キーの表示] を選択します。

  5. [key1] セクションで、 [接続文字列] の値を見つけます。 [クリップボードにコピー] アイコンを選択して、接続文字列をコピーします。 次のセクションで、この接続文字列の値を環境変数に追加します。

    Azure portal から接続文字列をコピーする方法を示すスクリーンショット

ストレージ接続文字列の構成

接続文字列をコピーした後、アプリケーションを実行しているローカル マシンの新しい環境変数にそれを書き込みます。 環境変数を設定するには、コンソール ウィンドウを開いて、お使いのオペレーティング システムの手順に従います。 <yourconnectionstring> は、実際の接続文字列に置き換えてください。

setx AZURE_STORAGE_CONNECTION_STRING "<yourconnectionstring>"

Windows で環境変数を追加した後、コマンド ウィンドウの新しいインスタンスを開始する必要があります。

プログラムの再起動

環境変数を追加した後、環境変数の読み取りを必要とする実行中のプログラムをすべて再起動します。 たとえば、続行する前に、ご使用の開発環境またはエディターを再起動します。

アプリに接続文字列を追加する

ストレージ アカウントにアクセスできるよう、アプリに接続文字列を追加します。

  1. Visual Studio Code に戻ります。

  2. Main メソッドで、Console.WriteLine("Hello, World"); コードを、環境変数から接続文字列を取得する次の行に置き換えます。

    string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
    
  3. キュー オブジェクトを作成する次のコードを Main に追加します。このキュー オブジェクトを後で送信メソッドと受信メソッドに渡します。

    QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
  4. ファイルを保存します。

キューにメッセージを挿入する

キューにメッセージを送信する新しいメソッドを作成します。

  1. 次の InsertMessageAsync メソッドを Program クラスに追加します。

    このメソッドには、キューの参照が渡されます。 まだキューがない場合は、CreateIfNotExistsAsync を呼び出すことによって新しいキューが作成されます。 次に、SendMessageAsync を呼び出すことによって、キューに newMessage が追加されます。

    static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
    {
        if (null != await theQueue.CreateIfNotExistsAsync())
        {
            Console.WriteLine("The queue was created.");
        }
    
        await theQueue.SendMessageAsync(newMessage);
    }
    
  2. 省略可能: 既定では、メッセージの最大 Time to Live は 7 日に設定されます。 メッセージの有効期限には、任意の正の数値を指定できます。 次のコード スニペットは、有効期限の "ない" メッセージを追加します。

    有効期限のないメッセージを追加するには、SendMessageAsync への呼び出しで Timespan.FromSeconds(-1) を使用します。

    await theQueue.SendMessageAsync(newMessage, default, TimeSpan.FromSeconds(-1), default);
    
  3. ファイルを保存します。

キュー メッセージは、UTF-8 エンコードを使用して、XML 要求と互換性のある形式にする必要があります。 メッセージの許容される最大サイズは 64 KB です。 メッセージにバイナリ データが含まれている場合は、メッセージを Base64 でエンコードしてください。

メッセージをデキューする

キューからメッセージを取得する新しいメソッドを作成します。 メッセージが正常に受け取られたら、何度も処理されないよう、キューから削除しておくことが重要です。

  1. RetrieveNextMessageAsync という新しいメソッドを Program クラスに追加します。

    このメソッドは、ReceiveMessagesAsync を呼び出してキューからメッセージを受け取ります。第 1 パラメーターに 1 を渡すと、キューにおける次のメッセージだけが取得されます。 メッセージを受け取ったら、DeleteMessageAsync を呼び出して、キューからそれを削除します。

    v12 より前のバージョンの SDK でメッセージがキューに送信されると、自動的に Base64 でエンコードされます。 v12 以降では、この機能は削除されています。 v12 SDK を使用してメッセージを取得しても、自動的に 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 メソッドを拡張します。

    static async Task Main(string[] args)
    {
        string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
    
        QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
        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;

namespace QueueApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");

            QueueClient queue = new QueueClient(connectionString, "mystoragequeue");

            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. すべてのメッセージが削除されるまでアプリの実行を続けます。 さらに 1 回実行すると、キューが空であるというメッセージとキューを削除するためのプロンプトが表示されます。

    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 Queue Storage キューを削除する

詳細については、Azure Queue Storage のクイックスタートを参照してください。

非推奨の .NET バージョン 11.x SDK を使用する関連コード サンプルについて、詳しくは「.NET バージョン 11.x を使用したコード サンプル」をご覧ください。