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 時間でオーバーロードを使用してみます。これが問題である場合は、この値をより適切な数値に微調整できます。もう 1 つのオプションは、一度に 1 つのメッセージだけを取得することです。

于 2011-04-06T04:53:35.680 に答える
1

Steve Marx からの別の回答は、基本的にストレージの例外を見て、先に進みます。これは他のフレームワークでも見たことがあります。: Steve Marx ブログ投稿

 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 に答える