2

我正在开发一个基于 Azure 的项目以进行一些研究,并且在从 CloudQueue 实例中删除消息时遇到了一些问题。代码相当简单,所以当我尝试从队列中删除消息时为什么会引发异常,我有点困惑。

这是为队列生成数据的代码:

foreach (var cell in scheme(cells))
{
    string id = Guid.NewGuid().ToString();
    var blob = sweepItemContainer.GetBlobReference(id);
    using (BlobStream stream = blob.OpenWrite())
    {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(stream, cell);
    }
    sweepItemQueue.AddMessage(new CloudQueueMessage(id), new TimeSpan(1, 0, 0));
}

以下是使用队列中数据的代码:

var msgs = sweepItemsQueue.GetMessages(MsgAmt);
foreach (var msg in msgs)
{
     _handleMessage(msg, sweepItemsContainer);
     sweepItemsQueue.DeleteMessage(msg);
     mergeItemsQueue.AddMessage(new CloudQueueMessage(msg.AsString), new TimeSpan(1, 0, 0));
}

我看不到消息如何不能存在于队列中。除了其他消费者之外,没有其他东西会改变队列。但我确信他们不能得到相同的信息(只要时间跨度没有用完),那么这是怎么发生的呢?

4

2 回答 2

2

您需要担心两个超时,消息在队列中存在多长时间(您已在调用中指定,以及在.AddMessage()调用时设置的可见性超时.GetMessages()(默认为 30 秒,有一个允许您指定超时的重载.GetMessages())。当您调用所有返回的消息时,其他消费者在“visibilityTimeout”期间不可见。一旦此期间结束,您尚未删除的所有消息都对所有其他消费者可见.

要检查这是否是问题,我会尝试使用.GetMessages()最大可见性超时 2 小时的重载。如果这是问题所在,您可以将此值微调为更合理的数字。另一种选择是一次只检索一条消息。

于 2011-04-06T04:53:35.680 回答
1

史蒂夫马克思的另一个回答,基本上是看看存储异常并继续前进。我也在其他框架中看到了这一点。: 史蒂夫马克思博客文章

 try
 {
    q.DeleteMessage(msg);
 }
 catch (StorageClientException ex)
 {
 if (ex.ExtendedErrorInformation.ErrorCode == "MessageNotFound")
 {
     // pop receipt must be invalid
     // ignore or log (so we can tune the visibility timeout)
 }
 else
 {
    // not the error we were expecting
     throw;
 }
}
于 2012-05-29T15:10:19.877 回答