2

I'm writing some functionality that responds to an Azure Service Bus Queue. This currently polls on a specified queue and OnMessage triggers a callback to a method in the original class that calls it:

    partial class Class1
    {
         private void BeginProcessing()
         {
             serviceBusHelper.Listen(QueueType.Inbound, HandleTransaction);
         }
         private bool HandleTransaction(BrokeredMessage message)
         {
             ...    
         }
    }

And then the service bus helper class:

public class ServiceBusHelper : IServiceBusHelper
{
    ManualResetEvent CompletedResetEvent = new ManualResetEvent(false);

    public void Listen(QueueType queue, Action<BrokeredMessage> callback)
    {

        switch (queue)
        {
            case QueueType.Inbound:
                inboundClient.OnMessage(message =>
                {
                    try
                    {
                        callback(message);
                    }
                    catch (Exception ex)
                    {
                        ...
                    }
                    CompletedResetEvent.WaitOne();
                });
                break;
            ...
        }
}

It is connecting correctly to the azure service bus queue and retrieving the message, however the callback never seems to actually trigger. What I'm trying to achieve is a service that will continuously respond to an OnMessage event, trigger a new worker (from within class1) despite the OnMessage actually being triggered from the ServiceBusHelper class.

2 Answers2

0

the callback never seems to actually trigger.

In order to reproduce the issue, I do a test in a console application with the following code on my side, which works fine.

public static void processmessage()
{
    string connectionString = "{connectionstring here}";

    var queueName = "{queue name}";

    var client = QueueClient.CreateFromConnectionString(connectionString, queueName);
    var options = new OnMessageOptions();
    options.AutoComplete = false;

    try
    {
        client.OnMessage(message =>
        {
            HandleTransaction(message);
        }, options);
    }
    catch (Exception)
    {

    }
}

private static void HandleTransaction(BrokeredMessage message)
{
    Console.WriteLine(String.Format("Message body: {0}", message.GetBody<String>()));
}

If possible, you can try to modify private bool HandleTransaction(BrokeredMessage message) to make it return void private void HandleTransaction(BrokeredMessage message), and check whether it works fine.

Fei Han
  • 26,415
  • 1
  • 30
  • 41
0

So I've managed to get this working by modifying to the asynchronous OnMessage counterpart. I believe the root cause was related to not specifing OnMessageOptions to the OnMessage, or the CompletedResetEvent not interacting how I expected.

    public void Listen(QueueType queue, Action<BrokeredMessage> callback)
    {
            OnMessageOptions options = new OnMessageOptions
            {   
                MaxConcurrentCalls = maxConcurrent,
                AutoComplete = false
            };

            switch (queue)
            {
                case QueueType.Inbound:
                    inboundClient.OnMessageAsync(async message =>
                    {
                        bool shouldAbandon = false;
                        try
                        {
                            callback(message);

                            // complete if successful processing
                            await message.CompleteAsync();
                        }
                        catch (Exception ex)
                        {
                            shouldAbandon = true;
                            Debug.WriteLine(ex);
                        }

                        if (shouldAbandon)
                        {
                            await m.AbandonAsync();
                        }
                    }, options);
                    break;

                ...
            }
    }