I have a windows service written in .NET 4 that creates multiple threads that contain infinitely running while(running) loops. When I stop the service, the running boolean becomes false and we break out of the while loop and once each thread does that, the service finally stops.
Inside the while, it calls oMessageReceiver.Receive(TimeSpan.FromSeconds(30)). so sometimes when I try to stop the service, I have to wait up to 30 seconds for the Receive() process to timeout.
One option would be to lower the timeout from 30 seconds to something smaller. I'm not sure of what performance penalties it'd incur, but since the process doesn't do any work without a BrokeredMessage, really I'd like to keep the listener open as often and long as possible.
I see that there is a .BeginReceive() method on the MessageReceiver. I have a sense there would be a programming pattern I could use here that would prevent my service from hanging while I was waiting for the Receive to timeout. Can anyone describe how to use the Begin/End APM functions in an infinitely running Windows Service?
In the new 2.1 Windows Azure SDK they have changed the Service Bus Worker Role template to use the OnMessage which recently was introduced in the 2.0 SDK. You can peek at that template to see what code it uses to get started. In this approach you set up an action to perform when a message arrives. In fact, you can also set a MaxConcurrentCalls property on the OnMessageOptions when setting it up which will handle your additional threads for you. If you used the OnMessage approach you'd do something similar where the service would close off the QueueClient so that it wouldn't process any more. You could also keep track with a synchronized indicator on if a message on ANY thread was processing and wait for only that processing to complete.
As for the best way to use the async methods (Begin/End) check out "Best Practices for Leveraging Windows Azure Service Bus Brokered Messaging" which has several examples.
Close the MessageFactory that the MessageReceiver was created from to cancel the receive operation. I had the same issue when calling Abort or Close on the MessageReceiver before closing the message factory.
Using the asynchronous Begin/End will make no difference. As a side note if you want to run asynchronously consider creating Task wrappers using TaskFactory.FromAsync to take advantage of the new async-await features.
Also see my answer on this question regarding the same issue:
Cancel an Azure Service Bus QueueClient long running Receive?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With