按值从Azure队列服务中删除邮件

时间:2017-08-20 11:08:23

标签: c# azure azure-storage asp.net-core-1.1 azure-queues

我正在使用Azure存储队列服务来跟踪多个不同客户端所排队的长时间运行的作业队列,但我现在要求从队列中删除与某些给定条件匹配的消息。

我意识到这对于队列来说有些反模式,但除了简单的排队(例如Delete MessagePeek Messages)之外,该服务确实提供了一些功能,所以我想我会尝试实施它。

我提出的解决方案是有效的,但不是很优雅且效率很低 - 而且我想知道它是否可以做得更好 - 或者我是否应该整理整个方法并使用支持这种方法的机制设计要求(这需要跨不同系统进行大量工作)。这是简化的代码:

        var queue = MethodThatGetsTheAppropriateQueueReference();
        await queue.FetchAttributesAsync(); //populates the current queue length
        if (queue.ApproximateMessageCount.HasValue)
        {
            // Get all messages and find any messages to be removed.
            //   this makes those messages unavailable for other clients 
            //   for the visibilityTimeOut period.
            //   I've set this to the minimum of 1 second - not ideal though
            var messages = await queue.GetMessagesAsync(queue.ApproximateMessageCount.Value);
            var messagesToDelete = messages.Where(x => x.AsString.Contains(someGuid));

            // Delete applicable messages
            messagesToDelete.ToList().ForEach(x => queue.DeleteMessageAsync(x));                
        }

注意最初我尝试使用PeekMessagesAsync()来避免影响不需要删除的邮件,但这不会为PopReceipt提供DeleteMessageAsync() 1}}。

问题:

  1. 有没有办法在不将所有消息拉下来的情况下执行此操作? (可能会有很多)
  2. 如果1不可能,如果我们使用PopReceipt,是否可以获取邮件的PeekMessagesAsync()

1 个答案:

答案 0 :(得分:2)

  

有没有办法在不删除所有邮件的情况下执行此操作?   (可能会有很多)

不幸的是没有。您必须Get条消息(一次最多32条)并分析消息内容以确定是否应删除该消息。

  

如果1不可能,有没有办法获取消息的PopReceipt   如果我们使用PeekMessagesAsync()?

再次,否。为了获得PopReceipt,必须将消息出列,这只能通过GetMessagesAsync()进行。 PeekMessagesAsync()只是在不改变其可见性的情况下返回消息。

可能的解决方案

您可能需要查看Service Bus Topics and Subscriptions这种功能。

您可以做的是创建一个topic,其中将发送所有邮件。

然后您将创建2 subscriptions:在一个订阅中,您将设置一个规则来检查匹配值的消息内容,而在其他订阅中,您将设置一个规则来检查消息内容是否不匹配值。

Azure Service Bus将执行的操作是检查根据规则到达的每条消息,并相应地按适当的订阅推送消息。通过这种方式,您可以很好地分离应该/不应该被删除的消息。