5

我无法将我的BrokeredMessage标记为 Complete。

像预期一样工作的简单代码:

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

     //do things with myObj

     message.Complete();            
 }

当我尝试等待用户完成myObj时,出现异常:

brokeredmessage已被处理

下面的代码:

 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

4 回答 4

2

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

一旦回调返回,BrokeredMessage就会被释放。

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

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

当您想将它们标记为完成时,它接收 aLockToken作为参数。

于 2017-09-03T07:54:27.020 回答
2

如果您正在执行异步方法,我发现这也是同样的问题,消息被调度并且在等待发生时,消息已经被释放。我只希望我早点找到这个帖子..

于 2018-03-21T07:48:27.083 回答
2

您不应存储代理消息本身。当您调用 .Complete() 方法时,根据文档会发生以下情况:

完成消息的接收操作,并指示该消息应标记为已处理并删除

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

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

在相关的代码中:

 var myObj= message.GetBody<MyObject>();
 ReceivedMessages.Add(myObj.Id, myObj);
于 2016-03-07T15:46:19.250 回答
0

看看 ServiceBus LockToken。

您可以调用 Complete(lockToken)

于 2016-09-08T15:50:29.920 回答