Сообщение System.MessageQueue (MSMQ) теряется, если во время его обработки происходит сбой моей функции? - PullRequest
3 голосов
/ 10 сентября 2009

Я отправляю сообщение, используя следующий код:

var transaction = new MessageQueueTransaction())
transaction.Begin(  );

var message = new Message
{
   Body = myContent,
   Recoverable = true
};

m_oMessageQueue.Send( message , myTransaction );

transaction.Commit( );

И получите его с помощью обработчика событий BeginRecieve и ReceiveCompleted.

Если мой обработчик событий завершится сбоем перед вызовом EndRecieve, должно ли сообщение оставаться в очереди и быть доступным для последующих вызовов, которые будут получены? Поведение, которое я вижу, состоит в том, что сообщение исчезло навсегда. (Или, может быть, есть тайм-аут, после которого он снова станет доступным?)

Обновление Код, получающий сообщение, выглядит следующим образом.

var messageQueue = new MessageQueue( myPath );
messageQueue.ReceiveCompleted += messageQueue_ReceiveCompleted_ThrowException;
messageQueue.BeginReceive();

В целях тестирования я выкидываю исключение в обработчик события messageQueue_ReceiveCompleted_ThrowException.

Затем я повторяю приведенный выше код с работающим обработчиком событий, но меня не вызывают.

Ответы [ 3 ]

9 голосов
/ 10 сентября 2009

Похоже, проблема в том, что вы используете BeginReceive с транзакционной очередью. Из MSDN :

Примечание Не используйте асинхронный вызовите BeginReceive с транзакциями. Если вы хотите выполнить транзакцию асинхронная операция, вызов BeginPeek, и поместите транзакцию и (синхронный) метод приема в обработчике событий, который вы создаете для заглянуть операции. Ваше событие Обработчик может содержать функциональность как показано в следующем коде C #.

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

2 голосов
/ 10 сентября 2009

Самым простым разрешением может быть использование BeginPeek или Peek для чтения содержимого сообщения без его удаления из очереди и после обработки сообщения, а затем удаления сообщения из очереди.

1 голос
/ 11 сентября 2009

Если очередь транзакционная, но удаленная, то вы можете получать сообщения только в транзакции с MSMQ 4.0.

Как получить транзакционный удаленный прием с MSMQ?

Приветствие Джон Бруквелл (MSFT)

...