Является ли MSMQ потокобезопасным?

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


person Raminder    schedule 22.10.2008    source источник


Ответы (3)


Сами операции потокобезопасны. Однако, если вы выполняете многошаговую операцию, вы можете обнаружить, что результаты не согласованы (например, просмотр, чтобы увидеть, есть ли данные в очереди, а затем вызов для получения данных только для того, чтобы обнаружить, что их больше нет).

person Brad Wilson    schedule 22.10.2008
comment
Обратите внимание: начиная с .NET Framework 4, согласно MSDN, Only the GetAllMessages method is thread safe. Я предлагаю обновить ответ, чтобы отразить это, чтобы читатели не были сбиты с толку. - person Iravanchi; 01.10.2014

Согласно MSDN:

Только следующие методы являются потокобезопасными: BeginPeek, BeginReceive, EndPeek(IAsyncResult), EndReceive(IAsyncResult), GetAllMessages, Peek и Receive.

person EggyBach    schedule 22.10.2008
comment
Обратите внимание, что в версии документации .Net 4 для MessageQueue указано, что только GetAllMessages() является потокобезопасным. Я предполагаю, что это фактическое изменение, поскольку ошибочная документация, вероятно, была бы обновлена ​​​​в соответствии с документацией .Net 4. - person redcalx; 26.03.2012
comment
Примечательно, что в моем модульном тесте было обнаружено, что метод Send() не является потокобезопасным, блокировка объекта MessageQueue разрешала различные исключения nullreference и т. д., которые возникали в моем параллельном цикле. - person Kaido; 02.08.2013
comment
@Kaido: Разблокированный MessageQueue.Send() привел к ошибкам? Или какое поведение вы испытали? - person Dio F; 30.10.2013
comment
Да, в коде платформы msft возникали исключения, когда я вызывал MessageQueue.Send() в одном экземпляре из нескольких потоков одновременно. Решено с помощью блокировки (myLockObj) {MessageQueue.Send();} - person Kaido; 31.10.2013

Вас может заинтересовать запись в блоге, которую я написал на эту тему. .

Короче говоря, MSMQ C++ API является потокобезопасным, но не все методы System.Messaging являются потокобезопасными. В записи блога я обсуждаю, как вызывать MessageQueue.Send потокобезопасным способом.

person Community    schedule 27.10.2008