BrokeredMessage处理完毕

时间:2016-03-07 15:25:38

标签: c# servicebus brokeredmessage

我将 BrokeredMessage 标记为完成时遇到问题。

简单的代码,按预期工作:

 private void OnMessageArrived(BrokeredMessage message)
 {
     var myObj= message.GetBody<MyObject>();

     //do things with myObj

     message.Complete();            
 }

当我尝试等待用户完成 myObj 时,我得到例外:

  已经处理了breakredmessage

以下代码:

 private Dictionary<long, BrokeredMessage> ReceivedMessages;      
 ReceivedMessages = new Dictionary<long, BrokeredMessage>();

 private void OnMessageArrived(BrokeredMessage message)
 {
     var myObj= message.GetBody<MyObject>();
     ReceivedMessages.Add(myObj.Id, message);

     //do things with myObj      
 }

 private void Button_Click(object sender, RoutedEventArgs e)
 {
     // get myObj on which user clicked

     ReceivedMessages[myObj.Id].Complete();
     ReceivedMessages.Remove(myObj.Id);        
 }

对我而言,似乎 ServiceBus c#中以某种方式失去与实际对象的连接

EF 中的分离对象类似,只是在这种情况下,对象与 ServiceBus

分离

编辑:

仅在用户点击按钮后将消息标记为完成对我很重要。 如果AC出现故障(或类似的事情),我希望消息仍保留在服务总线主题上,以便下次用户启动应用程序时,他将再次收到他未处理的消息。

4 个答案:

答案 0 :(得分:2)

您不应存储代理商本身。当您调用.Complete()方法时,会发生according to the documentation

完成邮件的接收操作,并指示邮件应标记为已处理和已删除

您应该做的是将 MyObject 类型的对象存储在字典中,因为已完成后将销毁代理消息。

private Dictionary<long, MyObject> ReceivedMessages;      
ReceivedMessages = new Dictionary<long, MyObject>();

在相关的代码中:

 var myObj= message.GetBody<MyObject>();
 ReceivedMessages.Add(myObj.Id, myObj);

答案 1 :(得分:2)

据我所知,这是非常隐含的,在文档中没有说明,但是当您订阅SB主题/订阅时,您只能访问BrokeredMessage对象的执行范围内的OnMessage对象。 1}}您提供给SubscriptionClient.OnMessage的回调委托。

回调返回后,BrokeredMessage将被处理。

如果要缓存邮件并将其标记为完成/放弃/死信,则应缓存BrokeredMessage.LockToken以及您需要的任何其他属性(如邮件正文),并使用

  • SubscriptionClient.Complete
  • SubscriptionClient.Abandon
  • SubscriptionClient.Deadletter

如果要将其标记为完整,则会收到LockToken作为参数。

答案 2 :(得分:2)

如果您正在执行异步方法,则会发现这是同一个问题,会调度消息,并且在等待发生时,消息已经被释放。我只希望我早点发现这篇文章..

答案 3 :(得分:0)

看看ServiceBus LockToken。

您可以调用Complete(lockToken)