XmlMessageFormatter生成正文中全为零的消息

时间:2018-08-21 00:13:21

标签: c# .net msmq

简单的实现;单进程读取(尽管多个任务可能异步编写)。

在大多数情况下,它似乎运行良好,但有时我们会收到一条消息,提示“车身尺寸”是合理的,但是如果您在“计算机管理”工具中查看它,则只能是“ 0”。这会导致阅读器上的XmlMessageFormatter失败。

我们添加了使我们能够更好地处理中毒邮件的代码,但是我们需要这些邮件,因此仅此一项是不可接受的。

对象:

public class SubscriptionData
{
  public Guid SubscriptionInstanceId { get; set; }
  public SubscriptionEntityTypes SubscriptionEntityType { get; set; }
  public List<int> Positions { get; set; }
  public List<EventInformation> Events { get; set; }
  public int SubscriptionId { get; set; }

  public SubscriptionData() { }

  public SubscriptionData(SubscriptionEntityTypes entityType, List<int> positions, List<EventInformation> events, int subscriptionId)
  {
    SubscriptionEntityType = entityType;
    Positions = positions;
    Events = events;
    SubscriptionId = subscriptionId;
    SubscriptionInstanceId = Guid.NewGuid();
  }

  public override string ToString()
  {
    return $"Entity Type: {SubscriptionEntityType}, Instance Id: {SubscriptionInstanceId}, Events: {string.Join("/", Events)}, SubsId: {SubscriptionId}";
  }
}

作家:

private static void ConstructMessageQueue()
{
  _messageQueue = MessageQueue.Exists(Queue) ?
    new MessageQueue(Queue) : MessageQueue.Create(Queue);
  _messageQueue.Label = QueueName;
}

private static void EnqueueSubscriptionData(SubscriptionEntityTypes entityType, List<int> positions, List<EventInformation> events, int subscriptionId)
{
  Task.Run(() =>
   {
     var subsData = new SubscriptionData(entityType, positions, events, subscriptionId);
     _logger.Info(ErrorLevel.Normal, $"Enqueuing subscription: {subsData}");
     _messageQueue.Send(subsData);
   });
}

阅读器:

private void HandleNotifications()
    {
        var mq = new MessageQueue(Queue);
        mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(SubscriptionData) });

        while (!_cancellationToken.IsCancellationRequested)
        {
            Message message = null;
            try
            {
                message = mq.Peek(TimeSpan.FromSeconds(5));

                if (message != null)
                {
                    var subsData = message.Body as SubscriptionData;
                    if (subsData == null)
                        continue;
                    _logger.Info(ErrorLevel.Normal, $"Processing subscription: {subsData}");

                    //  Process the notification here

                    mq.Receive();
                }
            }
            catch (MessageQueueException t) when (t.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
            {
                _logger.Info(ErrorLevel.Normal, $"Message Queue Peek Timeout");
                continue;
            }
            catch (MessageQueueException t)
            {
                _logger.Exception(t, "MessageQueueException while processing message queue for notifications");
                throw;
            }
            catch (Exception t)
            {
                _logger.Exception(t, "Exception while processing message queue for notifications");
            }
        }
    }

如果您很好奇,我被告知我们会偷看,只有在成功后才会收到,这样我们才不会失去信息,但是在阅读此书以尝试帮助我的同事时,看起来好像有交易。

The bad messages we get look like this.

1 个答案:

答案 0 :(得分:0)

似乎Send方法不是线程安全的,您不应在多个线程之间共享MessageQueue对象(您的_messageQueue静态变量)。在这里讨论:

Is MSMQ thread safe?