MSMQ первый Message.Body в очереди в порядке, все последующие Message.Body в очереди пусты - PullRequest
2 голосов
/ 14 мая 2010

Я отправляю несколько идентичных (кроме Id #, очевидно) сообщений в очередь MSMQ на моей локальной машине. Тело сообщений является сериализованным объектом XElement.

Когда я пытаюсь обработать первое сообщение в очереди, я могу успешно десериализовать объект Message.Body и сохранить его в файл. Однако при попытке обработать следующее (или любое последующее) сообщение Message.Body отсутствует, и выдается исключение. Я подтвердил, что идентификаторы сообщений верны для сообщения, которое пытается быть обработанным.

Сериализуемый XML сформирован правильно.

Есть идеи? Я основываю свой код на примере заказа книги Microsoft MSMQ, найденном здесь: http://msdn.microsoft.com/en-us/library/ms180970%28VS.80%29.aspx

// Create Envelope XML object
XElement envelope = new XElement( env + "Envelope"
                                , new XAttribute( XNamespace.Xmlns + "env"
                                                , env.NamespaceName       )
                                  <snip>            

//Send envelope as message body
MessageQueue myQueue = new MessageQueue(
    String.Format(@"FORMATNAME:DIRECT=OS:localhost\private$\mqsample")
);

myQueue.DefaultPropertiesToSend.Recoverable = true;

// Prepare message 
Message myMessage = new Message();
myMessage.ResponseQueue = new MessageQueue(
  String.Format(System.Globalization.CultureInfo.InvariantCulture,
                @"FORMATNAME:DIRECT=TCP:192.168.1.217\private$\mqdemoAck")
);

myMessage.Body = envelope;

// Send the message into the queue.
myQueue.Send(myMessage,"message label");

//Retrieve messages from queue            
System.Messaging.Message message = mqOrderQueue.Receive();

Значение Message.Body, которое я вижу при первом получении, соответствует ожидаемому: <?xml version="1.0" encoding="utf-8"?> <string>Some String</string> Тем не менее, вторая и последующие операции получения Message.Body: «Невозможно десериализовать сообщение, переданное в качестве аргумента. Не удается распознать формат сериализации. «

Как это работает нормально в первый раз, но не после этого? Я пробовал message.Dispose () после его получения, но это не помогло.

Большое спасибо за любую помощь в этом!

Ответы [ 3 ]

0 голосов
/ 14 мая 2010

Может быть, второе тело не содержит преамбулу XML, потому что объект все еще вокруг, который думает, что он уже написал это? Другими словами, у вас может быть состояние, которое нужно где-то очистить.

Я рекомендую смотреть на сообщения в консоли, как предложил kprobst.

0 голосов
/ 17 мая 2010

Мне удалось решить эту проблему, создав новый объект и назначив мой сериализованный «конверт» в качестве объекта внутри нового объекта (вместо того, чтобы назначать мой «конверт» непосредственно Message.Body.

//Class to create new message object
public class MsgToDB
{
    public int someInteger;
    public DateTime timeStamp;
    public XElement payload;
}

// Create an object of class MsgToDB which will contain envelope object 
MsgToDB testMsgObj = new MsgToDB();
testMsgObj.someInteger = 3;
testMsgObj.timeStamp = DateTime.Now;
testMsgObj.payload = envelope;

// Create and send message
Message testMsg = new Message(testMsgObj);
myQueue.Send(testMsg, "message label");

Спасибо всем за полезные советы.

0 голосов
/ 14 мая 2010

Если вы получите первое сообщение, а затем загрузите консоль управления, чтобы просмотреть очередь, и вы увидите тела в диалоге свойств для этих сообщений, то это может означать, что вы никогда не сохраняете тело для них. Может быть?

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

Затем снова получение по идентификатору идентифицирует точку в очереди, поэтому я никогда не использовал так много: D

...