BrokeredMessage处理完毕

top*_*olm 5 c# servicebus brokeredmessage

我将BrokeredMessage标记为Complete时遇到问题.

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

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

     //do things with myObj

     message.Complete();            
 }
Run Code Online (Sandbox Code Playgroud)

当我尝试等待用户完成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);        
 }
Run Code Online (Sandbox Code Playgroud)

对我来说,看起来ServiceBus在某种程度上失去了与c#中实际对象的连接

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

编辑:

只有在用户点击按钮后才能将消息标记为完成,这一点非常重要.如果AC关闭(或类似的事情),我希望消息仍然保留在服务总线主题上,以便下次用户启动应用程序时,他将再次接收他未处理的消息.

Ped*_*ias 2

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

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

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

private Dictionary<long, MyObject> ReceivedMessages;      
ReceivedMessages = new Dictionary<long, MyObject>();
Run Code Online (Sandbox Code Playgroud)

在相关的代码中:

 var myObj= message.GetBody<MyObject>();
 ReceivedMessages.Add(myObj.Id, myObj);
Run Code Online (Sandbox Code Playgroud)