6

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

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

应用程序中使用的代码:

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

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

访问 currentMessage.Body 时,有时会引发异常:

System.InvalidOperationException:接收消息时未检索到属性正文。确保 PropertyFilter 设置正确。

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

至于它是怎么变成这样的,有点神秘。Body 属性是默认值之一,我们绝对不会将其显式设置为 false。

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

4

3 回答 3

10

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

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

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

于 2011-10-19T15:45:37.320 回答
3

我也看到了它,并尝试使用我正在访问的属性来初始化它,而不是在其他任何地方设置它们。我会定期收到与您相同的错误,我的应用程序也是多线程的,我最终做的是捕获该错误并在收到错误时重新连接到 MSMQ。

于 2009-05-07T14:35:52.267 回答
1

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

您是否在多个线程中使用同一个MessageQueue实例而没有锁定?在这种情况下,你会遇到虚假的变化MessageReadPropertyFilter——至少我在尝试时遇到过。

为什么?因为

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

你能做什么?任何一个

  • 围绕对您的 messageQueue 的所有访问包裹一个锁 (_messageQueue) 或
  • 创建多个MessageQueue实例,每个线程一个
于 2014-05-20T03:47:16.173 回答