C# IBM.XMS IMessageConsumer-won';t释放-Can';不退订

C# IBM.XMS IMessageConsumer-won';t释放-Can';不退订,c#,ibm-mq,publish-subscribe,xms,C#,Ibm Mq,Publish Subscribe,Xms,第一:问题 我无法针对ibm的mq主题在异步持久订户上成功执行这些步骤 IMessageConsumer.MessageListener = null; IMessageConsumer.Close(); IMessageConsumer.Dispose(); ISession.Unsubscribe(topicPath); 我得到IBM.WMQ.MQException{“2428”} “无法使用MQCLOSE从主题X取消订阅。 删除订阅时可能出现问题,因为消息使用者正在使用该订阅。 请确保使

第一:问题 我无法针对ibm的mq主题在异步持久订户上成功执行这些步骤

IMessageConsumer.MessageListener = null;
IMessageConsumer.Close();
IMessageConsumer.Dispose();
ISession.Unsubscribe(topicPath);
我得到IBM.WMQ.MQException{“2428”} “无法使用MQCLOSE从主题X取消订阅。 删除订阅时可能出现问题,因为消息使用者正在使用该订阅。 请确保使用此订阅的所有邮件使用者在取消订阅之前都已关闭。有关详细信息,请参阅链接的异常。“

第二:细节 所以我使用的是IBM MQ基础设施。特别是他们的主题实现,用于分布式发布服务器/订阅服务器实现。我将整个过程包装在一个.NETWebAPI(MVC5)项目中,从组织的其他部分抽象出所有MQ细节。 暂时忽略所有故障转移等内容。当一个客户打电话进来时,我首先看看我们是否有一个呼叫方的会话。如果我们这样做,我使用现有的,如果不是,我从一个共享连接工厂制作一个新的。然后我为消费者创建一个新的目的地。接下来,我为特定主题路径创建持久订阅。然后我添加一个MessageListener并将整个混乱添加到内存缓存中。其他跟踪也在发生,但对本次讨论不重要

using IBM.XMS;

// Subscribe
MQConnectionFactory f = (MQConnectionFactory)fact;
SessionClass newSession = new SessionClass(); // Contains an ISession, IDestination, IMessageConsumer

newSession.Session = f.CreateSession();
newSession.Destination = newSession.Session.CreateTopic(MQConnectionFactory.FormatTopic(path));
newSession.Consumer = newSession.Session.CreateDurableSubscriber(newSession.Destination, subId.ToString());
newSession.Consumer.MessageListener = new MessageListener(MessageHandler);


// Message Handler - Some "details" removed
private void MessageHandler(IMessage msg)
{
    string topic = msg.GetStringProperty(MQConstants.TOPIC);
    DateTime timestamp = DateTime.FromBinary(msg.GetLongProperty(MQConstants.DATETIME));
    List<KeyValuePair<string, object>> parms = msg.GetStringProperty(MQConstants.PARAMETERS).FromBase64();
    object payload = msg.GetObjectProperty(MQConstants.PAYLOAD);

    Publication publication = new Publication()
    {
        MessageTimestamp = timestamp,
        Topic = topic,
        Parameters = parms
    };

    Callback.Notify(publication))
    _log.DebugFormat("Message delivered to {0}", msg.JMSMessageID);
    msg.Acknowledge();
}

// And for unsubscribe
SessionClass s = _destinations[fullPath];
s.Consumer.MessageListener = null;
s.Consumer.Close();
s.Consumer.Dispose();
s.Session.Unsubscribe(s.Destination.Name);
_destinations.Remove(fullPath);
说它基本上在使用中。我尝试在取消订阅之前停止连接,但也没有效果

有人有什么想法吗?因此,在创建MQ之后,我完全无法从MQ中删除任何订阅


谢谢

所以在更多地查看文档并与其他人进行更多的咨询之后,问题在于MQ文档不是最清晰的

需要传递给Unsubscribe方法的是传递给CreateDurableSubscriber方法的ID

所以…使用上面的代码,唯一的改变就是取消订阅呼叫

s.Session.Unsubscribe(subId.ToString());

然后一切都很好。

我应该提到,我已经用持久的newSession.Session.CreateDurableSubscriber和非持久的订阅newSession.Session.CreateConsumerHi dragonlipz测试了这一点。你能给我指一下你发现不清楚的文件吗?我想回顾一下可以做些什么来改进它,防止将来出现这种误解。谢谢。当然,谢谢你的留言。在CreateDurableSubscriber调用上,订阅(输入)和取消订阅(输入)并没有明确说明它们实际上是同一件事。这意味着其中一个上的值就是您将在另一个上使用的标识符。有道理,但容易被忽视。
s.Session.Unsubscribe(subId.ToString());