V
V
Vladislav2015-06-11 14:15:31
.NET
Vladislav, 2015-06-11 14:15:31

What happens to the BrokeredMessage after await is called on the db accessor?

There is some Worker Role which is twisted in Azure. Its task is to take messages from one ServiceBus queue, process them somehow and mark them in the database, and then form a new message based on the data from the first one and send it to another queue.
Let the first queue be called task, and the second - command.
We create clients:

_taskQueueClient = QueueClient.CreateFromConnectionString(CONNECTION_STRING, TASK_QUEUE_NAME);
_commandQueueClient = QueueClient.CreateFromConnectionString(CONNECTION_STRING, СOMMAND_QUEUE_NAME);

For the first queue in the Run method, we subscribe to the OnMessage events:
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = false; // Indicates if the message-pump should call complete on messages after the callback has completed processing.
options.MaxConcurrentCalls = 4; // Indicates the maximum number of concurrent calls to the callback the pump should initiate 

_taskQueueClient.OnMessage(Callback, options);

And create the following Callback method:
private async void Callback(BrokeredMessage receivedMessage)
{
   ///... некоторый код опущен
  
   await BusinessLayer.DoSomeWork1(arg);

   await BusinessLayer.DoSomeWork2(arg);

   await _commandQueueClient.SendAsync(new BrokeredMessage(data));  

   receivedMessage.Complete(); 
}

What could be happening behind the scenes during await BusinessLayer.DoSomeWork2(arg); that after it receivedMessage becomes Disposed?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Lastochkin, 2015-06-11
@SomeOneThere

After the execution of the first await, control in the Callback() call thread will return from it and the BrokeredMessage will cease to exist actively. The next await will be executed on a different thread, after DoSomeWork1() completes, and so on.
One of the solutions:

private async void Callback(BrokeredMessage receivedMessage)
{
CallbackPrim(receivedMessage).Wait(); // НЕ await!
}

private async void CallbackPrim(BrokeredMessage receivedMessage)
{
   ///... некоторый код опущен
  
   await BusinessLayer.DoSomeWork1(arg);

   await BusinessLayer.DoSomeWork2(arg);

   await _commandQueueClient.SendAsync(new BrokeredMessage(data));  

   receivedMessage.Complete(); 
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question