MessageReadPropertyFilter在使用MSMQ时重置

时间:2009-01-26 16:04:45

标签: msmq

奇怪的一个。我们有一个多线程应用程序,它从MSMQ队列中提取消息,然后根据消息执行操作。所有这些都是使用DTC完成的。

有时,由于某些原因我无法描述,我们在将消息从队列中拉出时会收到消息读取错误。

应用中使用的代码:

Message[] allMessagesOnQueue = this.messageQueue.GetAllMessages();

foreach (Message currentMessage in allMessagesOnQueue)
{
    if ((currentMessage.Body is IAMessageIDealWith))
    {
                // do something;    
    }
}

访问currentMessage.Body时,有时会抛出异常:

System.InvalidOperationException:收到邮件时未检索到Property Body。确保正确设置了PropertyFilter。

现在 - 这只在某些时候发生 - 看起来好像队列中的MessageReadPropertyFilter将Body属性设置为false。

至于它是如何变得有点神秘。 Body属性是默认值之一,我们absolutley从未明确地将其设置为false。

有没有其他人看到过这种行为,或者知道为什么这个值被设置为假?

3 个答案:

答案 0 :(得分:9)

如前所述,您可以通过System.Messaging.MessagePropertyFilter属性在messageQueue对象上可以访问的MessageReadPropertyFilter对象上显式设置布尔值。

如果您希望在收到或达到峰值时从消息中提取所有数据,请使用:

this.messageQueue.MessageReadPropertyFilter.SetAll(); // add this line
Message[] allMessagesOnQueue = this.messageQueue.GetAllMessages();
// ...

这可能会影响阅读许多邮件的效果,因此如果您只想要一些其他属性,请使用自定义标记创建一个新的MessagePropertyFilter

// Specify to retrieve selected properties.
MessagePropertyFilter filter= new MessagePropertyFilter();
filter.ClearAll();
filter.Body = true;
filter.Priority = true;
this.messageQueue.MessageReadPropertyFilter = filter;
Message[] allMessagesOnQueue = this.messageQueue.GetAllMessages();
// ...

您还可以使用以下方法将其重新设置为默认值:

this.messageQueue.MessageReadPropertyFilter.SetDefaults();

此处有更多信息:http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.messagereadpropertyfilter.aspx

答案 1 :(得分:3)

我也看过它,并尝试使用我明确设置的属性初始化它,而不是在其他地方设置它们。我定期得到你得到的同样的错误,我的应用程序也是多线程的,我最终做的是捕获该错误并在我得到它时重新连接到MSMQ。

答案 2 :(得分:1)

  

有时,由于某些原因我无法描述,我们在将消息从队列中拉出时会收到消息读取错误。

您是否使用了来自多个线程的相同MessageQueue个实例,而没有锁定?在这种情况下,你会遇到MessageReadPropertyFilter的虚假变化 - 至少在我尝试的时候我做了。

为什么呢? Because

  

只有GetAllMessages方法是线程安全的。

你能做什么?任

  • 围绕对messageQueue OR
  • 的所有访问包装锁(_messageQueue)
  • 创建多个MessageQueue个实例,每个线程一个