我有这个测试代码,可以永久地监听消息。如果它得到一个它打印出来。我想要做的是避免在每个get()之前构造一个MQMessage对象。如何重用MQMessage进行多次调用get()?
using System;
using IBM.WMQ;
namespace WMQ {
class Program {
static void Main(string[] args) {
string QueueManagerName = "A1PATA00";
string channelName = "ECACHE";
string connectionName = "A1PATA00.WORLDSPAN.COM(1414)";
var queueManager = new MQQueueManager(QueueManagerName, channelName, connectionName);
MQQueue get = queueManager.AccessQueue("SPLASH.ECAC.2", MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQGMO_FAIL_IF_QUIESCING);
var gmo = new MQGetMessageOptions();
gmo.Options = MQC.MQGMO_FAIL_IF_QUIESCING | MQC.MQGMO_WAIT;
gmo.WaitInterval = 10000000;// wait time
// var queueMessage = new MQMessage(); <--- i want to do this new once!
while (true) {
var queueMessage = new MQMessage(); // <-- only works if I do this every time i do a get
get.Get(queueMessage, gmo);
var strReturn = queueMessage.ReadString(queueMessage.MessageLength);
Console.WriteLine(strReturn);
}
}
}
}
答案 0 :(得分:2)
(1)请注意我在定义MQMessage对象的位置(非常重要)。
以下两个代码段之间的内存使用或速度基本没有区别:
(A)
MQMessage msg = null;
while (true)
{
msg = new MQMessage();
get.Get(msg, gmo);
Console.WriteLine(msg.ReadString(msg.MessageLength));
}
(B)
MQMessage msg = new MQMessage();
while (true)
{
get.Get(msg, gmo);
Console.WriteLine(msg.ReadString(msg.MessageLength));
msg.ClearMessage();
msg.MessageId = MQC.MQMI_NONE;
msg.CorrelationId = MQC.MQCI_NONE;
}
我更喜欢(A)因为它更清晰,更容易阅读。
(2)当你使用'var'时,你正在强迫.NET框架猜测你在做什么。做纯面向对象的编程。 即。
MQMessage msg = new MQMessage();
(3)在MQQueueManager中显式设置通道名称和连接名称不允许设置MQ安全信息。另外,不要使用MQEnvironment类,因为它不是线程安全的。将所有信息放在Hashtable中并将Hashtable传递给MQQueueManager类要好得多。以下是使用Hashtable for MQ连接信息的MQ .NET托管模式示例:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using IBM.WMQ;
namespace MQTest02
{
class MQTest02
{
private Hashtable inParms = null;
private Hashtable qMgrProp = null;
private System.String qManager;
private System.String outputQName;
/*
* The constructor
*/
public MQTest02()
: base()
{
}
/// <summary> Make sure the required parameters are present.</summary>
/// <returns> true/false
/// </returns>
private bool allParamsPresent()
{
bool b = inParms.ContainsKey("-h") && inParms.ContainsKey("-p") &&
inParms.ContainsKey("-c") && inParms.ContainsKey("-m") &&
inParms.ContainsKey("-q");
if (b)
{
try
{
System.Int32.Parse((System.String)inParms["-p"]);
}
catch (System.FormatException e)
{
b = false;
}
}
return b;
}
/// <summary> Extract the command-line parameters and initialize the MQ variables.</summary>
/// <param name="args">
/// </param>
/// <throws> IllegalArgumentException </throws>
private void init(System.String[] args)
{
inParms = Hashtable.Synchronized(new Hashtable());
if (args.Length > 0 && (args.Length % 2) == 0)
{
for (int i = 0; i < args.Length; i += 2)
{
inParms[args[i]] = args[i + 1];
}
}
else
{
throw new System.ArgumentException();
}
if (allParamsPresent())
{
qManager = ((System.String)inParms["-m"]);
outputQName = ((System.String)inParms["-q"]);
qMgrProp = new Hashtable();
qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
qMgrProp.Add(MQC.HOST_NAME_PROPERTY, ((System.String)inParms["-h"]));
qMgrProp.Add(MQC.CHANNEL_PROPERTY, ((System.String)inParms["-c"]));
try
{
qMgrProp.Add(MQC.PORT_PROPERTY, System.Int32.Parse((System.String)inParms["-p"]));
}
catch (System.FormatException e)
{
qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
}
if (inParms.ContainsKey("-u"))
qMgrProp.Add(MQC.USER_ID_PROPERTY, ((System.String)inParms["-u"]));
if (inParms.ContainsKey("-x"))
qMgrProp.Add(MQC.PASSWORD_PROPERTY, ((System.String)inParms["-x"]));
if (inParms.ContainsKey("-s"))
qMgrProp.Add(MQC.SECURITY_EXIT_PROPERTY, ((System.String)inParms["-s"]));
System.Console.Out.WriteLine("MQTest02:");
Console.WriteLine(" QMgrName ='{0}'", qManager);
Console.WriteLine(" Output QName ='{0}'", outputQName);
System.Console.Out.WriteLine("QMgr Property values:");
foreach (DictionaryEntry de in qMgrProp)
{
Console.WriteLine(" {0} = '{1}'", de.Key, de.Value);
}
}
else
{
throw new System.ArgumentException();
}
}
/// <summary> Connect, open queue, read a message, close queue and disconnect.
///
/// </summary>
/// <throws> MQException </throws>
private void testReceive()
{
MQQueueManager qMgr = null;
MQQueue queue = null;
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING;
MQGetMessageOptions gmo = new MQGetMessageOptions();
MQMessage receiveMsg = null;
try
{
qMgr = new MQQueueManager(qManager, qMgrProp);
System.Console.Out.WriteLine("MQTest02 successfully connected to " + qManager);
queue = qMgr.AccessQueue(outputQName, openOptions, null, null, null); // no alternate user id
System.Console.Out.WriteLine("MQTest02 successfully opened " + outputQName);
receiveMsg = new MQMessage();
queue.Get(receiveMsg, gmo);
System.Console.Out.WriteLine("Message Data>>>" + receiveMsg.ReadString(receiveMsg.MessageLength));
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("MQTest02 cc=" + mqex.CompletionCode + " : rc=" + mqex.ReasonCode);
}
catch (System.IO.IOException ioex)
{
System.Console.Out.WriteLine("MQTest02 ioex=" + ioex);
}
finally
{
try
{
queue.Close();
System.Console.Out.WriteLine("MQTest02 closed: " + outputQName);
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("MQTest02 cc=" + mqex.CompletionCode + " : rc=" + mqex.ReasonCode);
}
try
{
qMgr.Disconnect();
System.Console.Out.WriteLine("MQTest02 disconnected from " + qManager);
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("MQTest02 cc=" + mqex.CompletionCode + " : rc=" + mqex.ReasonCode);
}
}
}
/// <summary> main line</summary>
/// <param name="args">
/// </param>
// [STAThread]
public static void Main(System.String[] args)
{
MQTest02 mqt = new MQTest02();
try
{
mqt.init(args);
mqt.testReceive();
}
catch (System.ArgumentException e)
{
System.Console.Out.WriteLine("Usage: MQTest02 -h host -p port -c channel -m QueueManagerName -q QueueName [-u userID] [-x passwd] [-s securityExit]");
System.Environment.Exit(1);
}
catch (MQException e)
{
System.Console.Out.WriteLine(e);
System.Environment.Exit(1);
}
System.Environment.Exit(0);
}
}
}
要使用您的信息运行MQTest02,它将是:
MQTest02.exe -h A1PATA00.WORLDSPAN.COM -p 1414 -m A1PATA00 -c ECACHE -q SPLASH.ECAC.2
答案 1 :(得分:0)
在IBM MQ知识中心页面“ClearMessage method”中,它记录了以下内容:
此方法清除MQMessage对象的数据缓冲区部分。 数据缓冲区中的任何消息数据都会丢失,因为MessageLength, DataLength和DataOffset都设置为零。
消息描述符(MQMD)部分不受影响; 一个应用程序 可能需要在重用之前修改一些MQMD字段 MQMessage对象。要设置MQMD字段,请使用New替换 具有新实例的对象。
在IBM MQ知识中心页面“MQMessage .NET class”中,它记录了以下内容:
public byte [] MessageId {get;设置;}
对于MQQueue.Get调用,此字段指定消息标识符 要检索的消息。通常,队列管理器返回 带有消息标识符和相关标识符的第一条消息 与消息描述符字段匹配。 允许任何邮件标识符 使用特殊值MQC.MQMI_NONE 进行匹配。
public byte [] CorrelationId {get;设置;}
对于MQQueue.Get调用,消息的相关标识符为 检索。队列管理器返回带有的第一条消息 消息标识符和与消息匹配的相关标识符 描述符字段。 默认值MQC.MQCI_NONE可以帮助您 要匹配的相关标识符。
试试这个:
var queueMessage = new MQMessage(); <--- i want to do this new once!
while (true) {
//var queueMessage = new MQMessage(); // <-- only works if I do this every time i do a get
queueMessage.ClearMessage();
queueMessage.MessageId = MQC.MQMI_NONE;
queueMessage.CorrelationId = MQC.MQCI_NONE;
get.Get(queueMessage, gmo);