2013-08-02 156 views
0

我已經遇到了一個令人沮喪的問題,通過它的深度瀏覽一個隊列。我明白,打開的選項中需要使用MQOO_BROWSE選項打開隊列。然後在第一次讀取時使用獲取Messsage選項MQGMO_BROWSE_FIRST進行GET。最後,後續的GET應該使用MQGMO_BROWSE_NEXT選項。如何通過所有消息瀏覽Websphere MQ隊列?

問題是,我的嘗試只能檢索第一條消息!在第二次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 
} 

回答

6

這是令人沮喪,但我可以依靠這裏如此張貼,以驗證我是在正確的道路上的問題和答案。不幸的是,沒有任何答案能夠解決隨後的GET瀏覽問題,而且我被困住了。我在嘗試了一些毫無結果的其他途徑後找到了答案,而當我最終達成這一目標時,答案非常簡單。我決定發佈Q & A的解決方案。

很明顯,一旦GET進入MQMessage,除非您重新初始化它,否則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); 
} 

一旦我作出這種改變時,程序瀏覽所有隊列上的消息。

+0

感謝您回來並回答您自己的問題。 – nik0lias

+0

這幫了很多..謝謝 – GVR

4

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

如果再次使用同一個對象來獲得另一條消息,則Get實際上會試圖獲得一條消息,該消息具有之前檢索到的消息的MessageID。由於隊列中沒有消息與給定的MessageID匹配,因此Get調用將返回2033 - MQRC_NO_MSG_AVAILABLE

+0

這絕對是一個有益的補充問題。謝謝! – Cyberherbalist

4

對於簡單的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(); 
}