Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MessageReadPropertyFilter getting reset when using MSMQ

Tags:

msmq

Strange one. We have a multi-threaded app which pulls messages off a MSMQ Queue and then subsequently performs actions based on the messages. All of this is done using DTC.

Sometimes, for some reason I can't describe, we get message read errors when pulling Messages off the queue.

The code that is being used in the app:

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

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

When the currentMessage.Body is accessed, at times it throws an exception:

System.InvalidOperationException: Property Body was not retrieved when receiving the message. Ensure that the PropertyFilter is set correctly.

Now - this only happens some of the time - and it appears as though the MessageReadPropertyFilter on the queue has the Body property set to false.

As to how it gets like this is a bit of a mystery. The Body property is one of the defaults and we absolutley never explicitly set it to false.

Has anyone else seen this kind of behaivour or has some idea why this value is getting set to be false?

like image 318
Lachmania Avatar asked Jan 26 '09 16:01

Lachmania


1 Answers

As alluded to earlier, you could explicitly set the boolean values on the System.Messaging.MessagePropertyFilter object that is accessible on your messageQueue object via the MessageReadPropertyFilter property.

If you want all data to be extracted from a message when received or peaked, use:

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

That may hurt performance of reading many messages, so if you want just a few additional properties, create a new MessagePropertyFilter with custom flags:

// 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();
// ...

You can also set it back to default using:

this.messageQueue.MessageReadPropertyFilter.SetDefaults();

More info here: http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.messagereadpropertyfilter.aspx

like image 80
Keith Hickey Avatar answered Nov 28 '22 06:11

Keith Hickey