问题
I'm using the GitHub example to process the messages of a topic:
private void RegisterSubscriptionClientMessageHandler()
{
_subscriptionClient.RegisterMessageHandler(
async (message, token) =>
{
var eventName = $"{message.Label}{INTEGRATION_EVENT_SUFIX}";
var messageData = Encoding.UTF8.GetString(message.Body);
await ProcessEvent(eventName, messageData);
// Complete the message so that it is not received again.
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
},
new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 10, AutoComplete = false });
}
All messages are sent and received by all subscribers successfully, however in the command:
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
The following error always occurs:
ERROR ON ExceptionReceivedHandler EXEPTION: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue, or was received by a different receiver instance.
Bazinga.EventBus.Bus.EventBusSubscription:Error: ERROR ON ExceptionReceivedHandler EXEPTION: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue, or was received by a different receiver instance.
- Executing Action: UserCallback
Any tips on how to solve? Thank you!
回答1:
When a message is received from Service Bus Queue or Topic Subscription, a lock token will be returned with the message.
The lock token can be used to delete, dead letter or defer a message.
Every Queue and Topic Subscription has Lock duration property with it. Based on the time span configured for Lock duration, the lock supplied with the message will be expired.
Here, you are doing some processing await ProcessEvent(eventName, messageData);
before completing the message.
The problem must be the the lock gets expired before_subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
line is executed.
Increasing the lock duration or completing the message before calling ProcessEvent will solve your problem.
回答2:
The other main reason for this will be Autocomplete is enabled by default.
Whenever you are using CompleteAsync() then you should also instantiate an OnMessageOptions
object in order to set the set AutoComplete
to false
, and pass it into your OnMessage call.
OnMessageOptions onMessageOpt = new OnMessageOptions();
onMessageOpt.AutoComplete = false;
client.OnMessage(processCalculations, options);
See this Similar SO Solution
来源:https://stackoverflow.com/questions/52169119/azure-service-bus-exception-on-trye-to-complete-message