MessageReadPropertyFilter getting reset when using MSMQ
Asked Answered
L

3

7

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?

Lempira answered 26/1, 2009 at 16:4 Comment(0)
C
11

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

Craving answered 19/10, 2011 at 15:45 Comment(0)
P
3

I have seen it as well, and have tried initializing it with the properties I'm accessing explicitly set, and not setting them anywhere else. I periodically get the same error you are getting, my app is multi-threaded as well, what I ended up doing is trapping that error and reconnecting to MSMQ when I get it.

Prepare answered 7/5, 2009 at 14:35 Comment(0)
P
1

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

Are you using the same MessageQueue instance from more than one thread, without locking? In that case, you will encounter spurious changes in MessageReadPropertyFilter - at least I did, when I tried.

Why? Because

Only the GetAllMessages method is thread safe.

What can you do? Either

  • wrap a lock (_messageQueue) around all access to your messageQueue OR
  • create multiple MessageQueue instances, one per thread
Penland answered 20/5, 2014 at 3:47 Comment(1)
This was the answer for me. +1Acclamation

© 2022 - 2024 — McMap. All rights reserved.