简单的实现;单进程读取(尽管多个任务可能异步编写)。
在大多数情况下,它似乎运行良好,但有时我们会收到一条消息,提示“车身尺寸”是合理的,但是如果您在“计算机管理”工具中查看它,则只能是“ 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");
}
}
}
如果您很好奇,我被告知我们会偷看,只有在成功后才会收到,这样我们才不会失去信息,但是在阅读此书以尝试帮助我的同事时,看起来好像有交易。
答案 0 :(得分:0)
似乎Send方法不是线程安全的,您不应在多个线程之间共享MessageQueue对象(您的_messageQueue静态变量)。在这里讨论: