【问题标题】:How do I browse a Websphere MQ Queue through all messages?如何通过所有消息浏览 Websphere MQ 队列?
【发布时间】:2013-08-04 07:45:27
【问题描述】:

我在浏览队列时遇到了一个令人沮丧的问题。我了解需要使用打开选项中的 MQOO_BROWSE 选项打开队列。然后在第一次读取时使用获取消息选项 MQGMO_BROWSE_FIRST 执行 GET。最后,后续的 GET 应该使用 MQGMO_BROWSE_NEXT 选项。

问题是,我的尝试只检索到第一条消息!在第二次 GET 时,即使使用 MQGMO_BROWSE_NEXT,该方法也会抛出 MQRC_NO_MSG_AVAILABLE,即使队列中有 5 条消息!

这是我使用的代码:

IList<string> Messages = new List<string>();
_queueManager = new MQQueueManager(QueueManagerName);
int openOptions = MQC.MQOO_BROWSE  // open queue for browsing
_queue = QManager.AccessQueue(QueueName, openOptions);

MQGetMessageOptions mqGetMsgOpts = new MQGetMessageOptions();
mqGetMsgOpts.Options = MQC.MQGMO_BROWSE_FIRST;

MQMessage msg = new MQMessage();

_queue.Get(msg, mqGetMsgOpts);
MQGetMessageOptions mqGetNextMsgOpts = new MQGetMessageOptions();
mqGetNextMsgOpts.Options = MQC.MQGMO_BROWSE_NEXT;

try
{
    while (true)
    {
        string messageText = msg.ReadString(msg.MessageLength);
        Messages.Add(messageText);
        _queue.Get(msg, mqGetNextMsgOpts);
    }
}
catch (MQException ex)
{
    // Handle it
}

【问题讨论】:

    标签: c# ibm-mq


    【解决方案1】:

    这令人沮丧,但我能够依靠 SO 上发布的问题和答案来验证我是否走在正确的道路上。不幸的是,没有一个答案解决了随后的 GET 浏览问题,我被难住了。在尝试了许多无果而终的其他路径后,我得到了答案,当我终于找到它时,它很简单。我决定发布我的解决方案的问答。

    显然,一旦对 MQMessage 进行了 GET,除非您重新初始化它,否则 GET 无法获取下一条消息,并且会立即抛出 MQRC_NO_MSG_AVAILABLE 异常。在执行 GET 之前重新初始化 MQMessage 实例可以解决问题。我通过在 while 循环中的 GET 之前添加所需的代码行来修改上面的代码:

    while (true)
    {
        string messageText = msg.ReadString(msg.MessageLength);
        Messages.Add(messageText);
        msg = new MQMessage();
        _queue.Get(msg, mqGetNextMsgOpts);
    }
    

    一旦我做出这个改变,例程就会浏览队列中的所有消息。

    【讨论】:

    • 感谢您回来回答您自己的问题。
    • 这太棒了!我知道它很旧,但这对我有很大帮助!给其他读者的一个提示:您不必从 First 开始。如果您刚刚打开队列,则可以立即使用 Next。只有当您重用已打开的队列并想重新开始时,您才需要 First。
    【解决方案2】:

    是的,没错。每个Get 方法调用都需要MQMessage 的新实例。当Get 方法返回一条消息时,MQMessage 对象将使用从队列/主题中检索到的消息头和消息体进行初始化。例如,MessageId 属性使用消息的消息 ID 进行初始化。

    如果再次使用同一个对象来获取另一条消息,Get 实际上会尝试获取一条消息,该消息具有之前检索到的消息的MessageID。由于队列中没有消息匹配给定的MessageID,因此Get 调用返回2033 - MQRC_NO_MSG_AVAILABLE

    【讨论】:

    • 这绝对是对问题的有用补充。谢谢!
    【解决方案3】:

    对于简单的 C# 程序,创建一个新的 MQMessage 对象很好,但对于需要处理数千或数百万条消息的长时间运行的程序,这不是一个好方法。重用对象要好得多。

    string messageText;
    MQMessage msg = new MQMessage();
    while (true)
    {
        smessageText = msg.ReadString(msg.MessageLength);
        Messages.Add(messageText);
        _queue.Get(msg, mqGetNextMsgOpts);
        // Clear both MsgID and CorrelID for next use.
        msg.MessageId = MQC.MQMI_NONE;
        msg.CorrelationId = MQC.MQCI_NONE;
        // Optional, remove data from the message
        msg.ClearMessage();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多