I'm having an intermittent problem with the Azure Service bus. Sporadically, placing a message on the bus causes the following exception:
TYPE: InvalidOperationException
MESSAGE: The operation cannot be performed because the brokered message '723eab13dab34351a78bb687d0923b89' has already been consumed. Please use a new BrokeredMessage instance for the operation.
STACKTRACE
at Microsoft.ServiceBus.Messaging.MessagingUtilities.ValidateAndSetConsumedMessages(IEnumerable`1 messages)
at Microsoft.ServiceBus.Messaging.MessageSender.Send(TrackingContext trackingContext, IEnumerable`1 messages, TimeSpan timeout)
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.<>c__DisplayClass1.<ExecuteAction>b__0()
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)
at IQ.IR.Core.ServiceBus.AzureBus`1.Enqueue(T message) in c:\BuildAgent\work\cc0c51104c02a4e9\IQ.IR.Core\ServiceBus\AzureBus.cs:line 69
...Rest of stacktrace snipped as it's within my app
The offending code from AzureBus is:
public void Enqueue(T message)
{
using (var brokeredMessage = new BrokeredMessage(message) { Label = message.GetType().FullName, TimeToLive = _timeToLive })
{
_retryPolicy.ExecuteAction(() => _sender.Send(brokeredMessage));
}
}
Where T message being passed in is
[Serializable]
public class ValidationMessage
{
public string ValidationToken { get; set;}
}
And _retryPolicy is a
RetryPolicy<ServiceBusTransientErrorDetectionStrategy>
_timeToLive is a 12 hour timespan
Any ideas?
.... and to pile on to Abhishek's answer: Right now you need to construct a new BrokeredMessage for each retry, so your retry policy scope needs to be one level further up. Mind that if you put in a stream, we will use that stream as-is inside the brokered message and pull straight fro it onto the wire, so you will need to make copies of the stream ahead of time for a retry loop.
I recently ran into this and found another cause: if you are constructing a BrokeredMessage and set a break point prior to sending it with your MessageSender, and inspect the properties on the Message, it will attempt to access the Queue and throw this exception. Simply sending the message first without inspecting its properties in the IDE will not cause this problem.
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