C# 如何通过所有消息浏览Websphere MQ队列?

C# 如何通过所有消息浏览Websphere MQ队列?,c#,ibm-mq,C#,Ibm Mq,我在浏览队列时遇到了一个令人沮丧的问题。我知道队列需要使用打开选项中的MQOO_BROWSE选项打开。然后在第一次读取时,首先使用GET-message选项MQGMO_-BROWSE_执行GET。最后,后续GET应该使用MQGMO_BROWSE_NEXT选项 问题是,我的尝试只是为了检索第一条消息!在第二次GET时,即使使用MQGMO_BROWSE_NEXT,该方法也会抛出MQRC_NO_MSG_AVAILABLE,即使队列中有5条消息 以下是我使用的代码: IList<string>

我在浏览队列时遇到了一个令人沮丧的问题。我知道队列需要使用打开选项中的MQOO_BROWSE选项打开。然后在第一次读取时,首先使用GET-message选项MQGMO_-BROWSE_执行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
}
IList Messages=new List();
_queueManager=新的MQQueueManager(QueueManagerName);
int openOptions=MQC.MQOO_BROWSE//打开队列进行浏览
_queue=QManager.AccessQueue(QueueName,openOptions);
MQGetMessageOptions mqGetMsgOpts=新的MQGetMessageOptions();
mqGetMsgOpts.Options=MQC.MQGMO_BROWSE_FIRST;
MQMessage msg=新MQMessage();
_Get(msg,mqGetMsgOpts);
MQGetMessageOptions mqGetNextMsgOpts=新MQGetMessageOptions();
mqGetNextMsgOpts.Options=MQC.MQGMO_BROWSE_NEXT;
尝试
{
while(true)
{
字符串messageText=msg.ReadString(msg.MessageLength);
Messages.Add(messageText);
_Get(msg,mqGetNextMsgOpts);
}
}
捕获(MQException-ex)
{
//处理它
}

这让我很沮丧,但我可以依靠这里发布的问题和答案来验证我是否走上了正确的道路。不幸的是,没有一个答案是通过浏览得到的,我被难住了。我在尝试了许多没有结果的其他途径后找到了答案,当我最终找到答案时,答案非常简单。我决定发布我的有效解决方案的问答

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

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

一旦我做了这个更改,例程就会浏览队列上的所有消息。

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

如果再次使用同一对象来获取另一条消息,则
get
实际上会尝试获取一条包含以前检索到的消息的
MessageID
的消息。由于队列中没有消息与给定的
MessageID
匹配,因此
Get
调用返回
2033
-
MQRC\u no\u MSG\u AVAILABLE

对于简单的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();
}

这无疑是对问题的有益补充。谢谢谢谢你回来回答你自己的问题。这太棒了!我知道它很旧,但这帮了我不少忙!给其他读者的一个建议是:你不必从第一个开始。如果您刚刚打开队列,您可以立即使用Next。只有在重用已打开的队列并希望重新开始时,才需要首先。