簡體   English   中英

如何通過所有消息瀏覽Websphere MQ隊列?

[英]How do I browse a Websphere MQ Queue through all messages?

我遇到了一個令人沮喪的問題,一直到深入瀏覽隊列。 我知道需要在打開選項中使用MQOO_BROWSE選項打開隊列。 然后在第一次讀取時使用Get Messsage Option 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
}

這令人沮喪,但我能夠依靠這里發布的問題和答案來驗證我是在正確的道路上。 不幸的是,沒有一個答案通過瀏覽解決了隨后的GET問題,而且我很難過。 在嘗試了許多毫無結果的其他路徑之后,我得到了答案,當我最終找到它時,它非常簡單。 我決定發布我的解決方案的Q&A。

顯然,一旦對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);
}

完成此更改后,例程瀏覽隊列中的所有消息。

對,那是正確的。 每個Get方法調用都需要一個新的MQMessage實例。 Get方法返回消息時, MQMessage對象將使用從隊列/主題檢索的消息標題和消息正文進行初始化。 例如,使用消息的消息ID初始化MessageId屬性。

如果再次使用相同的對象來獲取另一條消息,則Get實際上會嘗試獲取具有之前檢索到的消息的MessageID的消息。 由於隊列中沒有消息與給定的MessageID匹配,因此Get調用返回2033 - MQRC_NO_MSG_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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM