Azure Documentation

Tutorial: Working with Azure Storage Queue Messages

This tutorial guides you through the process of sending, receiving, and deleting messages from an Azure Storage Queue using C#.

Prerequisites

Step 1: Set up your Project

1

Create a new .NET Console Application project. You can do this using the .NET CLI:

dotnet new console -n AzureQueueMessageDemo

Navigate to your project directory:

cd AzureQueueMessageDemo
2

Add the necessary NuGet package for Azure Storage Queues:

dotnet add package Azure.Storage.Queues

Step 2: Connect to your Azure Storage Queue

3

You'll need your Azure Storage account connection string. You can find this in the Azure portal under your Storage Account's "Access keys" section.

In your Program.cs file, you'll need to initialize the QueueClient. For security, it's best practice to store connection strings in environment variables or Azure Key Vault.

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

public class Program
{
    public static async Task Main(string[] args)
    {
        // Replace with your actual connection string and queue name
        string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
        string queueName = "my-message-queue";

        if (string.IsNullOrEmpty(connectionString))
        {
            Console.WriteLine("AZURE_STORAGE_CONNECTION_STRING environment variable not set.");
            return;
        }

        // Create a QueueClient
        QueueClient queueClient = new QueueClient(connectionString, queueName);

        // Ensure the queue exists
        await queueClient.CreateIfNotExistsAsync();

        Console.WriteLine($"Connected to queue: {queueName}");

        // Proceed with sending and receiving messages...
    }
}

Step 3: Send a Message

4

To send a message, use the SendMessageAsync method. The message content is a simple string.

// Inside Main method, after QueueClient initialization
string messageContent = "Hello from the Azure Queue Tutorial!";
await queueClient.SendMessageAsync(messageContent);
Console.WriteLine($"Sent message: '{messageContent}'");

Step 4: Receive a Message

5

You can peek at messages without removing them using PeekMessageAsync, or receive and dequeue them using ReceiveMessageAsync.

When you receive a message, it becomes invisible for a specified duration (visibility timeout) before it reappears if not deleted.

// Inside Main method, after sending message
Console.WriteLine("Waiting for a message...");
var response = await queueClient.ReceiveMessageAsync();
var message = response.Value;

if (message != null)
{
    Console.WriteLine($"Received message: '{message.MessageText}'");
    Console.WriteLine($"Message ID: {message.MessageId}");
    Console.WriteLine($"Pop Receipt: {message.PopReceipt}"); // Needed for deletion

    // Process the message here...

    // Delete the message after processing
    await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
    Console.WriteLine("Message deleted.");
}
else
{
    Console.WriteLine("No messages in the queue.");
}
Note: The ReceiveMessageAsync method by default retrieves one message and makes it invisible for 30 seconds. You can configure the visibility timeout when sending messages or receiving them.

Step 5: Delete a Message

6

As shown in Step 4, you must explicitly delete a message after you have successfully processed it. This requires the message's MessageId and its PopReceipt.

// As shown in the receive message example:
await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);

Full Example (Program.cs)

7

Here's the complete Program.cs code for this tutorial:

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

public class Program
{
    public static async Task Main(string[] args)
    {
        // Replace with your actual connection string and queue name
        string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
        string queueName = "my-message-queue"; // Or any name you prefer

        if (string.IsNullOrEmpty(connectionString))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("ERROR: AZURE_STORAGE_CONNECTION_STRING environment variable not set.");
            Console.ResetColor();
            Console.WriteLine("Please set the environment variable with your Azure Storage connection string.");
            return;
        }

        Console.WriteLine($"Attempting to connect to queue: {queueName}");

        try
        {
            // Create a QueueClient
            QueueClient queueClient = new QueueClient(connectionString, queueName);

            // Ensure the queue exists
            await queueClient.CreateIfNotExistsAsync();
            Console.WriteLine($"Queue '{queueName}' ensured.");

            // --- Send a Message ---
            string messageContentToSend = $"Message sent at: {DateTime.UtcNow}";
            Console.WriteLine($"Sending message: '{messageContentToSend}'");
            var sendResponse = await queueClient.SendMessageAsync(messageContentToSend);
            Console.WriteLine($"Message sent successfully. Message ID: {sendResponse.Value.MessageId}");

            // --- Receive and Process a Message ---
            Console.WriteLine("Waiting for a message to receive...");
            // ReceiveMessageAsync returns a single message and makes it invisible.
            // Default visibility timeout is 30 seconds.
            var receiveResponse = await queueClient.ReceiveMessageAsync();
            var message = receiveResponse.Value;

            if (message != null)
            {
                Console.WriteLine($"\n--- Received Message ---");
                Console.WriteLine($"Message ID: {message.MessageId}");
                Console.WriteLine($"Content: '{message.MessageText}'");
                Console.WriteLine($"Inserted On: {message.InsertedOn}");
                Console.WriteLine($"Expires On: {message.ExpiresOn}");
                Console.WriteLine($"Pop Receipt: {message.PopReceipt}");
                Console.WriteLine($"Dequeue Count: {message.DequeueCount}");
                Console.WriteLine($"------------------------");

                // Simulate message processing
                Console.WriteLine("Processing message...");
                await Task.Delay(2000); // Simulate work
                Console.WriteLine("Message processed.");

                // --- Delete the Message ---
                Console.WriteLine($"Deleting message ID: {message.MessageId}...");
                await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
                Console.WriteLine("Message deleted successfully.");
            }
            else
            {
                Console.WriteLine("No messages were available in the queue.");
            }

            // --- Example of peeking at messages (does not remove them) ---
            Console.WriteLine("\nPeeking at messages...");
            var peekResponse = await queueClient.PeekMessageAsync();
            var peekedMessage = peekResponse.Value;
            if(peekedMessage != null)
            {
                Console.WriteLine($"Peeked Message ID: {peekedMessage.MessageId}");
                Console.WriteLine($"Peeked Content: '{peekedMessage.MessageText}'");
            }
            else
            {
                Console.WriteLine("No messages to peek at.");
            }
        }
        catch (Exception ex)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"An error occurred: {ex.Message}");
            Console.ResetColor();
        }

        Console.WriteLine("\nTutorial finished. Press Enter to exit.");
        Console.ReadLine();
    }
}

Running the Tutorial

  1. Set the AZURE_STORAGE_CONNECTION_STRING environment variable with your Azure Storage account connection string.
  2. Run the application using the .NET CLI:
    dotnet run
Important: For production environments, consider using Azure Key Vault to securely manage your connection strings.

You have now learned the basics of sending, receiving, and deleting messages from Azure Storage Queues. This is fundamental for building decoupled, scalable applications on Azure.