Azure队列在DeleteMessage上抛出异常

时间:2011-04-06 03:36:59

标签: c# .net azure azure-queues

我正在研究基于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));
}

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

2 个答案:

答案 0 :(得分:2)

您需要担心两个超时,消息在队列中存在多长时间(您在.AddMessage()调用中指定的消息以及调用{{1时设置的可见性超时) (默认情况下,这是30秒,有一个overload,允许您指定超时)。当您调用.GetMessages()时,所有返回的消息对于期间'visibilityTimeout的其他消费者是不可见的'。这段时间结束后,所有其他消费者都无法看到您尚未删除的所有消息。

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

答案 1 :(得分:1)

史蒂夫马克思的另一个答案,基本上看看存储异常并继续前进。我也在其他框架中看到了这个: Steve Marx blog post

 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;
 }
}