MessageReadPropertyFilter получает сброс при использовании MSMQ - PullRequest
4 голосов
/ 26 января 2009

Странный. У нас есть многопоточное приложение, которое извлекает сообщения из очереди 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.

Кто-нибудь еще видел такого рода поведение или имеет какое-то представление, почему это значение устанавливается в ложь?

Ответы [ 3 ]

9 голосов
/ 19 октября 2011

Как упоминалось ранее, вы можете явно установить логические значения для объекта 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

3 голосов
/ 07 мая 2009

Я также видел это и пытался инициализировать его со свойствами, к которым я обращаюсь, которые были явно установлены, и не устанавливать их где-либо еще. Я периодически получаю ту же ошибку, что и вы, мое приложение также является многопоточным, и в итоге я перехватил эту ошибку и снова подключился к MSMQ, когда я ее получил.

1 голос
/ 20 мая 2014

Иногда, по какой-то причине, которую я не могу описать, мы получаем ошибки чтения сообщений при удалении сообщений из очереди.

Используете ли вы один и тот же MessageQueue экземпляр из нескольких потоков без блокировки? В этом случае вы встретите ложные изменения в MessageReadPropertyFilter - по крайней мере, я это сделал, когда пытался.

Почему? Поскольку

Только метод GetAllMessages является поточно-ориентированным.

Что вы можете сделать? Или

  • обернуть блокировку (_messageQueue) вокруг всего доступа к вашему сообщениюQueue ИЛИ
  • создать несколько MessageQueue экземпляров, по одному на поток
...