重用MQMessage对象

时间:2017-02-13 23:10:54

标签: c# ibm-mq

我有这个测试代码,可以永久地监听消息。如果它得到一个它打印出来。我想要做的是避免在每个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);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

  1. 当我看到这样的问题时,我摇摇头。你不 理解.NET VM(框架)中的面向对象概念 垃圾收集。
  2. 另外,为什么不编写纯C#代码?
  3. 最后,在一个安全非常重要的世界里,你的代码确实如此 不支持SSL / TLS和/或UserID&amp;密码验证。
  4. (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);