Programmatically access a queue

Completed

Queues hold messages - packets of data whose shape is known to the sender application and receiver application. The sender creates the queue and adds a message. The receiver retrieves a message, processes it, and then deletes the message from the queue. The following illustration shows a typical flow of this process.

An illustration showing a typical message flow through the Azure Queue.

Notice that get and delete are separate operations. This arrangement handles potential failures in the receiver and implements a concept called at-least-once delivery. After the receiver gets a message, that message remains in the queue but is invisible for 30 seconds. If the receiver crashes or experiences a power failure during processing, then it will never delete the message from the queue. After 30 seconds, the message will reappear in the queue and another instance of the receiver can process it to completion.

How to connect to a queue

You already saw how to connect to a queue in the last unit using the QueueClient class. The QueueClient constructor takes the connection string and name of the queue that your application wants to connect to. Then the QueueClient class contains methods to send messages to, peek at messages on, and receive messages from the queue.

QueueClient queueClient = new QueueClient(connectionString, queueName);

You would create one QueueClient object for each queue that your application talks to. You would then pass the QueueClient instance to whatever methods in your code that need to access the queue. The QueueClient class is thread-safe so a single instance can be used throughout your application.

How to send a message

To send a message, you call the a SendMessageAsync method on a QueueClient object. The simplest way to send a message is to just pass a string to the SendMessageAsync` method.

Response<SendReceipt> response = await queueClient.SendMessageAsync("This is a message");

Typically though, when exchanging data between applications, a message needs to contain multiple fields of data. For this reason, messages are often passed in a structured format like JSON to the queue. To do this, you need to first serialize an object representing the message to JSON and then pass the resulting JSON to the queue.

string messageJson = JsonSerializer.Serialize(objectData);
Response<SendReceipt> response = await queueClient.SendMessageAsync(messageJson);

To include binary data in the message, first Base64 encode the binary data into a string. Then, the Base64 encoded string can then be sent to the storage queue, either directly or as a property on a JSON object.

Note

While the total queue size can be up to 500 TB, the individual messages in it can only be up to 64 KB in size (48 KB when using Base64 encoding). If you need a larger payload you can combine queues and blobs – passing the URL to the actual data (stored as a Blob) in the message. This approach would allow you to enqueue up to 4.77 TB in a Block Blob. The increased blob size better supports a diverse range of scenarios, from media companies storing and processing 4K and 8K videos to cancer researchers sequencing DNA.

How to peek at messages

Sometimes your application may need to peek at a message in the queue without dequeuing the message. This is done by calling the PeekMessageAsync method on the QueueClient class. Accessing the Value property of the Response class gives you access to the PeekedMessage object.

Response<PeekedMessage> response = await queueClient.PeekMessageAsync();
PeekedMessage message = response.Value;

Console.WriteLine($"Message id  : {message.MessageId}");
Console.WriteLine($"Inserted on : {message.InsertedOn}");

How to receive and delete a message

When the receiver application is ready to process a message, it calls the ReceiveMessageAsync method on the QueueClient object to pull the next message off of the queue. A QueueMessage object represents the message and can be accessed By using the Value property on the Response object.

The QueueMessage class contains properties to get the message ID, when the message was inserted into the queue and several others. The most important property though is the Body property which contains the contents of the message. If the message was formatted as JSON, you can use the ToObjectFromJson method to convert the message into the appropriate object type.

Response<QueueMessage> response = await queueClient.ReceiveMessageAsync();
QueueMessage message = response.Value;
NewsArticle article = message.Body.ToObjectFromJson<NewsArticle>();

When you are finished processing this message, you need to delete this message from the queue. This insures no other consumers pick up this message and process it. You do this by calling the DeleteMessageAsync method on the QueueClient object. You will need to provide the values of the MessageId and PopReceipt properties of the QueueMessage that you want to be deleted from the queue.

await queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);

Let's now apply this new knowledge to our application!