1

我有一個控制檯應用程序來讀取Azure服務總線上預訂中存在的所有代理消息。我在那裏有大約3500條消息。這是我讀取消息的代碼:SubscriptionClient.RecieveBatch不檢索所有代理消息

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. 我無法從服務總線中刪除並重新創建主題/訂閱。

編輯:

我用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(); 
    } 
    } 

我在訂閱消息。當第一次調用peekBatch時,它會獲得250條消息。所以它進入了帶有PeekBatch(250,3225)的while循環。每次只收到250條消息。我在輸出列表中輸入的最終消息總數爲,包含重複項。我無法理解這是如何發生的。

回答

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指導

注:似乎有是某種你可以查看消息的數量大小限制一次。我嘗試了不同的訂閱,並且獲取的消息數量各不相同。

+0

我在我的回答中提到過。 「通過在PeekBatch下面使用相同的SubscriptionClient,最後拉取的序列號會保留,因爲在循環時它應該保持跟蹤並穿過整個隊列。」 – MikeWo

+0

@MikeWo對不起,我沒有在這裏看到你的答案,但在SO中的其他問題。實際上,在我看到你的答案之前,我正在根據你的答案在其他地方使用peekbatch。 – nitinvertigo

+0

@MikeWo PeekBatch檢索的郵件數量是否有限制?它適用於3200,但是當訂閱上有5000條消息時,它會顯示此錯誤:內部服務器錯誤:服務器沒有提供有意義的答覆;這可能是由於會話過早關閉造成的。 – nitinvertigo

2

您正在寫作的主題是爲了偶然分割嗎?當您從分區實體接收消息時,它將一次只從其中一個分區獲取消息。 From MSDN

「當客戶端想要從分區隊列中接收消息或從訂閱分區主題接收消息時,Service Bus會查詢所有消息片段,然後返回從任何消息返回的第一條消息消息存儲到接收方Service Bus緩存其他消息,並在接收到其他接收請求時返回它們;接收客戶端不知道分區;分區隊列或主題的面向客戶端的行爲(例如,讀取,完成,延期,死書,預取)與正規實體的行爲相同。「

這可能不是一個好主意,即使對於一個非分區實體,您也可以使用Receive或Peek方法完成所有消息。以更小的批次循環消息會更加有效,特別是如果消息具有適當的大小或者大小不確定。

由於您實際上並不想從隊列中刪除郵件,我建議使用PeekBatch而不是ReceiveBatch。這可以讓您獲得該消息的副本並且不會將其鎖定。我強烈建議使用與PeekBatch一起使用相同的SubscriptionClient的循環。通過在引擎蓋下使用與PeekBatch相同的SubscriptionClient,最後拉取的序列號會保留,因爲在循環時應該跟蹤並遍歷整個隊列。這基本上可以讓你閱讀整個隊列。

+0

嗨,感謝您的回覆。我正在使用PeekBatch方法,並有一些問題。我已經更新了這個問題。你可以看看它。 – nitinvertigo

0

我遇到了類似的問題,其中client.ReceiveBatchAsync(....)不會從azure服務總線中的訂閱檢索任何數據。

經過一番挖掘後,我發現每個訂閱者都有一點需要啓用批量操作。這隻能通過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。雖然它至少仍未加載所有消息,但它開始清除隊列。據我所知,批量大小參數僅作爲服務總線的建議,但不是一個規則。

希望它有幫助!