Below I have a fairly simple .NET console app consuming an Azure Service Bus Queue.
As you'll see, I am using Task.Factory to fire up 25 receiver tasks that then call my APM-style BeginMessageReceive method. Then, at the end of EndMessageReceive, I call BeginMessageReceive again to keep the loop going.
My question is how could I achieve the same sort of thing but switching from the APM-style BeginMessageReceive/EndMessageReceive to a TPL/TAP approach using recursive Tasks and possibly utilizing C# 5.0 async/await?
using System;
using System.Configuration;
using System.Threading.Tasks;
using Microsoft.ServiceBus.Messaging;
namespace ServiceBusConsumer
{
class Program
{
private static QueueClient _queueClient;
private static void Main(string[] args)
{
var connectionString = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"];
_queueClient = QueueClient.CreateFromConnectionString(connectionString, "MyQueue");
for (var i = 0; i < 25; i++ )
{
Task.Factory.StartNew(BeginMessageReceive);
}
Console.WriteLine("Waiting for messages...");
Console.ReadKey();
_queueClient.Close();
} //end private static void Main(string[] args)
private static void BeginMessageReceive()
{
_queueClient.BeginReceive(TimeSpan.FromMinutes(5), EndMessageReceive, null);
}
private static void EndMessageReceive(IAsyncResult iar)
{
var message = _queueClient.EndReceive(iar);
try
{
if (message != null)
{
var msg = message.GetBody<string>();
Console.WriteLine("Message: " + msg);
if (_queueClient.Mode == ReceiveMode.PeekLock)
{
// Mark brokered message as completed at which point it's removed from the queue.
message.Complete();
}
}
}
catch (Exception ex)
{
if (_queueClient.Mode == ReceiveMode.PeekLock)
{
// unlock the message and make it available
message.Abandon();
}
Console.WriteLine("Exception was thrown: " + ex.GetBaseException().Message);
}
finally
{
if (message != null)
{
message.Dispose();
}
}
BeginMessageReceive();
}
}
}
New modified code for recursively call itself again if the MessageReceive timeout expires:
private static async Task MessageReceiveAsync()
{
while (true)
{
using (var message = await _queueClient.ReceiveAsync(TimeSpan.FromMinutes(5)))try
{
if (message != null)
{
try
{
var msg = message.GetBody<string>();
Console.WriteLine("Message: " + msg);
if (_queueClient.Mode == ReceiveMode.PeekLock)
{
// Mark brokered message as completed at which point it's removed from the queue.
await message.CompleteAsync();
}
}
catch (Exception ex)
{
message.AbandonAsync();
Console.WriteLine("Exception was thrown: " + ex.GetBaseException().Message);
}
}
}
}
}