如何在Azure Service Bus主题上删除DeadLetter消息

时间:2013-12-04 14:41:14

标签: c# azure queue azureservicebus dead-letter

我正在编写一段代码,以便我们:

  1. 查看Azure Service Bus主题(Peek)
  2. 中存在的所有死信消息的列表
  3. 修复并将其发送回主题
  4. 重新发送时从死信队列中删除它们。
  5. 前2分我没有问题;使用Peek接收模式,我可以显示消息列表,我们可以编辑和重新发送,没有任何问题。

    当我想要从死信队列中删除消息时,问题出现了。

    我们如何通过消息级别对消息执行此操作?我们可能只想删除驻留在死信队列中的2条消息,并保留其他消息以便稍后查看。在死信队列中的消息上调用.Complete()是否像在主订阅中那样删除它?

    供参考;这是我们为死信队列获取SubscriptionClient的代码:

    private SubscriptionClient GetOrCreateSubscriptionClient(string connectionString)
    {
        if (!NamespaceManager.TopicExists(_topicName))
        {
            NamespaceManager.CreateTopic(new TopicDescription(_topicName)
            {
                MaxSizeInMegabytes = 5120,
                DefaultMessageTimeToLive = TimeSpan.FromSeconds(DEFAULT_LOCK_DURATION_IN_SECONDS)
            });
        }
    
        if (!NamespaceManager.SubscriptionExists(_topicName, _subscriptionName))
        {
            NamespaceManager.CreateSubscription(_topicName, _subscriptionName);
        }
    
        var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(_topicName, _subscriptionName);
    
        var client = SubscriptionClient.CreateFromConnectionString(
            connectionString, deadLetterPath, _subscriptionName, ReceiveMode.PeekLock);
    
        return client;
    
    }
    

2 个答案:

答案 0 :(得分:9)

是的,在对死信队列中收到的代理消息的引用上调用complete将把它从死信队列中删除。

答案 1 :(得分:1)

以下是如何获取死信队列中所有消息的列表:

public async Task<IEnumerable<BrokeredMessage>> GetDeadLetterMessagesAsync(string connectionString,
    string queueName)
{
    var queue = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
    var messageList = new List<BrokeredMessage>();
    BrokeredMessage message;
    do
    {
        message = await queue.PeekAsync();
        if (message != null)
        {
            messageList.Add(message);
        }
    } while (message != null);
    return messageList;
}

使用SequenceNumber,您可以删除特定消息:

public async Task DeleteDeadLetterMessageAsync(string connectionString, string queueName, long sequenceNumber)
{
    var deadLetterQueue = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
    var msg = await deadLetterQueue.PeekAsync(sequenceNumber);
    if (msg.SequenceNumber == sequenceNumber)
    {
        msg = await deadLetterQueue.ReceiveAsync();
        await msg.CompleteAsync();
    }
}

请注意,如果没有任何带有指定SequenceNumber的消息,Peek可能会返回另一条消息。因此,您需要检查SequenceNumber,以便不删除错误的消息。