0

我使用 IBM XMS.NET 创建了一个应用程序。一切都很好,我可以从队列中读取消息。我只想阅读那些 2 分钟后旧的消息。在这种情况下如何使用选择器。下面是我创建的代码。

 var time = 120000; // 2 mins in miliseconds
 var currentTime = (DateTime.Now - DateTime.MinValue).TotalMilliseconds; // current time in milliseconds
 long finaltime = Convert.ToInt64(currentTime - time); // Time in milliseconds after substracting 2 minutes
var dtt = Convert.ToInt64(((new DateTime(1970, 01, 01, 01, 00, 00)) - DateTime.MinValue).TotalMilliseconds); // Time in miliseconds till 1970
 finaltime = finaltime - dtt;  // substracting milliseconds till 1976 as JMSTimestamp shows time after 1970
string selector = "JMSTimestamp <=" + finaltime.ToString();

这里选择器设置为固定值,例如 1454322340382。我如何设置选择器以选择最新的 DateTime.Now,然后查找比 DateTime.Now 更早的消息 - 2 分钟。

4

2 回答 2

2

选择那些超过 2 分钟的消息可能是查看这些消息的最低效的方式。你没有说你为什么要这样做。如果您只是想丢弃它们,那么我建议您让消息的生产者在这些消息上添加到期时间。如果您无法让消息的生产者更改他们的应用程序来执行此操作,那么请考虑使用 CAPEXPRY 管理覆盖。

如果您想查看它们,那么浏览所有消息并仅对正确年龄的消息进行操作会比选择它们更有效,我敢肯定。

于 2016-02-02T04:13:57.647 回答
1

因为选择器是在创建消费者时作为参数传递的,所以可以在不关闭和重新创建消费者的情况下更改它。

MessageConsumer receiver;
receiver = session.createConsumer(stockQueue, selector);

更新:

选择器表达式的评估发生在创建消费者的过程中。DateTime.Now - 2 表达式的计算结果为固定值并且不会更改。例如“JMSTimestamp <= 1454322340382”。因此,当使用该选择字符串创建消费者时,消费者将仅获得符合上述条件的那些消息。

虽然以上都很好。但是当消费者获取消息时,新消息可以进入队列。当消费者尝试获取它们时,这些消息可能会超过 2 分钟。即使它们超过两分钟,消费者也不会收到这些消息,因为它们JMSTimestamp更高,例如 1454666666666。要删除此类消息,您必须关闭消费者并使用更新的选择器条件再次创建它。

希望我清楚。

对于您的用例,我会选择 MQ Base .NET API 而不是 XMS .NET。首先浏览消息,如果消息超过 2 分钟,请将其删除。

  queueBrowse = queueManager.AccessQueue(strQueueName, MQC.MQOO_BROWSE + MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);

  try
  {
      MQMessage msgBrowse = new MQMessage();
      MQGetMessageOptions mqgmoBrowse = new MQGetMessageOptions();
      mqgmoBrowse.Options = MQC.MQGMO_BROWSE_NEXT;
      queueBrowse.Get(msgBrowse, mqgmoBrowse);
      TimeSpan ts = DateTime.Now.ToUniversalTime().Subtract(msgBrowse.PutDateTime);
      if (ts.TotalMinutes > 2)
      {
          MQMessage msgDelete = new MQMessage();
          msgDelete.MessageId = msgBrowse.MessageId;
          MQGetMessageOptions mqgmo = new MQGetMessageOptions();
          mqgmo.MatchOptions = MQC.MQMO_MATCH_MSG_ID;
          queueBrowse.Get(msgDelete, mqgmo);
          Console.WriteLine("Message older than 2 minutes deleted");
       }
       else
       {
           Console.WriteLine("Message not older than 2 minutes");
       }
  }
  catch (MQException ex)
  {
  }
于 2016-02-01T17:14:50.693 回答