SubscriptionClient.RecieveBatch不检索所有代理消息

时间:2015-10-19 08:03:16

标签: c# azure azureservicebus azure-servicebus-queues azure-servicebus-topics

我有一个控制台应用程序来读取Azure Service Bus上订阅中存在的所有代理消息。我在那里有大约3500条消息。这是我阅读消息的代码:

SubscriptionClient client = messagingFactory.CreateSubscriptionClient(topic, subscription);   
long count = namespaceManager.GetSubscription(topic, subscription).MessageCountDetails.ActiveMessageCount;
Console.WriteLine("Total messages to process : {0}", count.ToString()); //Here the number is showing correctly
IEnumerable<BrokeredMessage> dlIE = null;
dlIE = client.ReceiveBatch(Convert.ToInt32(count));

当我执行代码时,在dlIE中,我只能看到256条消息。我也试过像这个client.PrefetchCount那样给出预取计数,但是它也只返回256条消息。

我认为一次可以检索的消息数有一些限制。但是msdn页面上没有提到RecieveBatch方法的内容。我该怎样做才能一次检索所有邮件?

注意:

  1. 我只想阅读邮件,然后让它存在于服务总线上。因此,我不使用message.complete方法。

  2. 我无法从服务总线中删除并重新创建主题/订阅。

  3. 修改

    我使用PeekBatch而不是ReceiveBatch:

        IEnumerable<BrokeredMessage> dlIE = null;
                                List<BrokeredMessage> bmList = new List<BrokeredMessage>();
      long i = 0;
       dlIE = subsciptionClient.PeekBatch(Convert.ToInt32(count)); // count is the total number of messages in the subscription.
      bmList.AddRange(dlIE);
      i = dlIE.Count();
     if(i < count)
      {           
     while(i < count)
      {
      IEnumerable<BrokeredMessage> dlTemp = null;
       dlTemp = subsciptionClient.PeekBatch(i, Convert.ToInt32(count));
        bmList.AddRange(dlTemp);
        i = i + dlTemp.Count();
        }
        }
    

    我在订阅中有 3255 条消息。当第一次调用peekBatch时,它会获得250条消息。所以它进入PeekBatch(250,3225)的while循环。每次只收到250封邮件。我在输出列表中的最终总消息是 3500 ,带有重复项。我无法理解这是怎么回事。

3 个答案:

答案 0 :(得分:2)

您正在撰写的主题是否偶然分区?当您从分区实体接收消息时,它将一次仅从其中一个分区获取。 From MSDN

&#34;当客户端想要从分区队列或分区主题的订阅接收消息时,Service Bus会查询所有片段以获取消息,然后返回从任何片段返回的消息消息存储到接收器。 Service Bus缓存其他消息,并在收到其他接收请求时返回它们。接收客户端不知道分区;分区队列或主题的面向客户端的行为(例如,读取,完成,延迟,死亡,预取)与常规实体的行为相同。&#34;

假设即使使用非分区实体,您也可以一次性使用Receive或Peek方法获取所有消息,这可能不是一个好主意。以更小的批次循环消息会更有效率,特别是如果您的消息具有任何合适的大小或者大小不确定。

由于您实际上并不想从队列中删除邮件,因此我建议使用PeekBatch而不是ReceiveBatch。这样您就可以获得邮件的副本并且不会锁定它。我强烈建议使用与PeekBatch相同的SubscriptionClient循环。通过使用与PeekBatch相同的SubscriptionClient,最后提取的序列号将保持不变,因为您应该跟踪并遍历整个队列。这基本上可以让你读完整个队列。

答案 1 :(得分:1)

我已经弄清楚了。订阅客户端会记住它检索到的最后一批,再次调用时,会检索下一批。

所以代码是:

    IEnumerable<BrokeredMessage> dlIE = null;
List<BrokeredMessage> bmList = new List<BrokeredMessage>();
  long i = 0;  
  while (i < count)
  {
   dlIE = subsciptionClient.PeekBatch(Convert.ToInt32(count));
   bmList.AddRange(dlIE);
   i = i + dlIE.Count();
  }

感谢MikeWo的指导

注意:您可以一次查看的邮件数量似乎有某种大小限制。我尝试了不同的订阅,每个提取的消息数量各不相同。

答案 2 :(得分:0)

我遇到了类似的问题,client.ReceiveBatchAsync(....)无法从天蓝色服务总线中的订阅中检索任何数据。

经过一番挖掘后,我发现每个用户都有一点可以启用批量操作。这只能通过powershell启用。以下是我使用的命令:

$subObject = Get-AzureRmServiceBusSubscription -ResourceGroup '#resourceName' -NamespaceName '#namespaceName' -Topic '#topicName' -SubscriptionName '#subscriptionName' 
$subObject.EnableBatchedOperations = $True

Set-AzureRmServiceBusSubscription -ResourceGroup '#resourceName' -NamespaceName '#namespaceName' -Topic '#topicName'-SubscriptionObj $subObject

可以找到更多详细信息here。虽然它仍然没有加载所有消息,但它至少开始清除队列。据我所知,批量大小参数仅作为服务总线的建议而不是规则。

希望它有所帮助!