Microsoft Azureサービスバスを使用してコマンドメッセージを送信しており、OnMessageアプローチを使用してバスから取得しています。 IMessageSessionAsyncHandler.OnMessageAsyncの実装では、メッセージの処理準備ができていないことがわかります。だから私はバスからメッセージを受け取り、キューの最後まで読んでみたい。 get/readd操作はアトミックでなければなりません。どうすればこれを達成できますか?Azureサービスバス - キューの最後までのOnMessageAsyncでのReadメッセージ
私の現在の解決策(高度に抽象化されている)ですが、非アトミック性を恐れています。
queueClient.RegisterSessionHandlerFactory(new CommandSessionHandlerFactory(queueClient), ...);
internal class CommandSessionHandlerFactory : IMessageSessionAsyncHandlerFactory
{
private readonly QueueClient _queueClient;
public CommandSessionHandlerFactory(QueueClient queueClient)
{
_queueClient = queueClient;
}
public IMessageSessionAsyncHandler CreateInstance(MessageSession session, BrokeredMessage message)
{
return new CommandSessionHandlerAsync(_queueClient);
}
}
internal class CommandSessionHandlerAsync : MessageSessionAsyncHandler
{
private readonly QueueClient _queueClient;
public CommandSessionHandlerAsync(QueueClient queueClient)
{
_queueClient = queueClient;
}
protected override async Task OnMessageAsync(MessageSession session, BrokeredMessage message)
{
if (!messageReadyForProcessing)
{
// How to get the following code transactional safe?
var clonedMessage = message.Clone();
await message.CompleteAsync();
await _queueClient.SendAsync(clonedMessage);
}
}
}
そして、団体検出はどうですか?複製されたメッセージのMessageIdを変更して、サービスバスの重複検出によってクローンメッセージが破棄されないようにする必要がありますか?
1)メッセージXの前に処理する必要がある他のメッセージがあるので、メッセージXをキューの最後に置く必要があるため、放棄は適切ではありません。2)messageReadyForProcessingはセッションに基づく決定です。したがって、あなたの最後の提案は残念ながら、私たちがすでにセッションに入っているので私たちが行く方法ではありません。 –
私は、終わりまたは始まりのキューに放棄した後に何が起こるか、鋭い答えを見つけることができないことがわかります。しかし、私はあなたがトランザクションスコープを使用できる私の答えを編集しました。 –
ありがとうございました。私はTransactionScopeについて読んだことがありますが、私たちの場合にはうまくいきませんでした。 "async"に関する疑問について:.NET Framework 4.5.1以降はうまくいくようです。 TransactionScopeの新しいコンストラクタ、TransactionScopeAsyncFlowOptionがあります:http://stackoverflow.com/questions/13543254/get-transactionscope-to-work-with-async-await/17527759#17527759あなたの例にパラメータを追加します。 –