Messaging using BeginReceive and EndReceive on ServiceBus does not work for me

789 Views Asked by At

I need asynchronous messaging on the bus.

This is the code I'm using:

    //set callback to get the message
    MessageReceiver messageReceiver = MessagingFactory.CreateMessageReceiver(BaseTopicName + "/subscriptions/" + addressee, 
        ReceiveMode.PeekLock);
    IAsyncResult result = messageReceiver.BeginReceive(AsyncGet, messageReceiver);
    Debug.WriteLine("After BeginReceive");
    // Wait for the WaitHandle to become signaled.
    Thread.Sleep(0);
    result.AsyncWaitHandle.WaitOne();
    // Close the wait handle.
    result.AsyncWaitHandle.Close();
    //return the information
    Debug.WriteLine("return the information");

Here is the AsyncGet:

public void AsyncGet(IAsyncResult result)
{
    Debug.WriteLine("Start AsyncGet");
    MessageReceiver messageReceiver = result.AsyncState as MessageReceiver;
    BrokeredMessage = messageReceiver.EndReceive(result);
    Debug.WriteLine("Finish AsyncGet");
    messageReceiver.Close();
}

The output I get is:

    After BeginReceive
    return the information
    Start AsyncGet
    Finish AsyncGet

It says that the line result.AsyncWaitHandle.WaitOne(); did not stop execution until the thread of AsyncGet finishes, as I thought it should. Please,tell me what I'm doing wrong here. Thanks!

1

There are 1 best solutions below

0
On

I just double-checked the source code. This is by design.

The wait handle on the IAsyncResult gets triggered as the operation completes and before the callback gets invoked. The callback and the wait handle on the async result are two alternate methods to wait for completion of the operation. To achieve what you want to do here - blocking your thread based on completion of the operation and get the response through the callback - you'd need to have an explicit wait handle (ManualResetEvent) in your app and Set() that to signaled as the callback fires.