Receive Messages from an Azure Storage Queue

This tutorial guides you through the process of retrieving messages from an Azure Storage Queue using C#. You'll learn how to peek at messages without deleting them and how to retrieve and delete messages.

Prerequisites

Before you begin, ensure you have the following:

Create a Queue and Add Messages (Optional)

If you don't have an existing queue with messages, you can create one and add some messages first. Here's a simple example using C#:

using Azure.Storage.Queues;

// Replace with your actual connection string or emulator URI
string connectionString = "UseDevelopmentStorage=true";
string queueName = "my-sample-queue";

// Create the queue client
QueueClient queueClient = new QueueClient(connectionString, queueName);

// Create the queue if it doesn't exist
queueClient.CreateIfNotExists();

// Add a message to the queue
queueClient.SendMessage("This is the first message.");
queueClient.SendMessage("This is the second message.");

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

Receive and Process Messages

The primary method for receiving messages is ReceiveMessageAsync() on the QueueClient. This method retrieves the next message available in the queue.

Peeking at Messages

Sometimes you might want to inspect a message without removing it from the queue. This is useful for debugging or for conditional processing. Use PeekMessageAsync() for this purpose.

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

// ... (connection string and queue name setup as above)

QueueClient queueClient = new QueueClient(connectionString, queueName);

// Peek at the next message
PeekedMessage nextMessage = await queueClient.PeekMessageAsync();

if (nextMessage != null)
{
    Console.WriteLine($"Peeked Message: {nextMessage.MessageText}");
    Console.WriteLine($"Message ID: {nextMessage.MessageId}");
    Console.WriteLine($"Insertion Time: {nextMessage.InsertedOn}");
}
else
{
    Console.WriteLine("The queue is empty.");
}

Retrieving and Deleting Messages

To process a message and then remove it from the queue, you use ReceiveMessageAsync(). This method returns a QueueMessage object. Once you have processed the message, you must explicitly delete it using its MessageId and PopReceipt to prevent it from being dequeued again.

Important: Messages retrieved with ReceiveMessageAsync() are invisible to other clients for a default visibility timeout (usually 30 seconds). If you don't delete the message within this timeout, it will reappear in the queue.
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;
using System;
using System.Threading.Tasks;

// ... (connection string and queue name setup as above)

QueueClient queueClient = new QueueClient(connectionString, queueName);

// Receive the next message
QueueMessage message = await queueClient.ReceiveMessageAsync();

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

    // --- Process the message here ---
    // For example, log it, update a database, etc.
    Console.WriteLine("Message processed successfully.");

    // Delete the message from the queue
    await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
    Console.WriteLine($"Message {message.MessageId} deleted.");
}
else
{
    Console.WriteLine("The queue is empty or no messages are available.");
}

Dequeueing Multiple Messages

You can retrieve a batch of messages using ReceiveMessagesAsync(int maxMessages). This can improve efficiency by reducing the number of network requests.

using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

// ... (connection string and queue name setup as above)

QueueClient queueClient = new QueueClient(connectionString, queueName);

int maxMessagesToRetrieve = 5; // Retrieve up to 5 messages

// Receive a batch of messages
Response<QueueMessage[]> response = await queueClient.ReceiveMessagesAsync(maxMessagesToRetrieve);
QueueMessage[] messages = response.Value;

if (messages.Length > 0)
{
    Console.WriteLine($"Retrieved {messages.Length} messages.");
    foreach (QueueMessage msg in messages)
    {
        Console.WriteLine($"Processing message: {msg.MessageText}");
        Console.WriteLine($"Message ID: {msg.MessageId}");

        // --- Process each message here ---

        // Delete the message after processing
        await queueClient.DeleteMessageAsync(msg.MessageId, msg.PopReceipt);
        Console.WriteLine($"Deleted message: {msg.MessageId}");
    }
}
else
{
    Console.WriteLine("No messages received.");
}

Handling Visibility Timeout

If your message processing takes longer than the visibility timeout, the message will become visible again in the queue. You can extend the visibility timeout of a message using UpdateMessageAsync().

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

// ... (connection string and queue name setup as above)

QueueClient queueClient = new QueueClient(connectionString, queueName);

QueueMessage message = await queueClient.ReceiveMessageAsync();

if (message != null)
{
    Console.WriteLine($"Received Message: {message.MessageText}");

    // Simulate a long-running process
    await Task.Delay(TimeSpan.FromSeconds(40)); // Longer than default visibility timeout

    // Extend the visibility timeout
    await queueClient.UpdateMessageAsync(
        message.MessageId,
        message.PopReceipt,
        TimeSpan.FromMinutes(5)); // New visibility timeout of 5 minutes

    Console.WriteLine($"Extended visibility timeout for message {message.MessageId}.");

    // After processing, you would still delete it
    // await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
}

Next Steps