У меня есть несколько процессов, отслеживающих очередь MSMQ. Я хочу выполнять многоэтапные операции, например, сначала просмотреть сообщение, а затем на основе некоторых критериев получить сообщение. Одно сообщение может пройти критерии получения нескольких процессов, поэтому несколько процессов могут попытаться получить одно и то же сообщение. Будут ли эти операции потокобезопасными? Если нет, что мне делать, чтобы один процесс не смог получить сообщение, которое уже получил другой процесс?
Является ли MSMQ потокобезопасным?
Ответы (3)
Сами операции потокобезопасны. Однако, если вы выполняете многошаговую операцию, вы можете обнаружить, что результаты не согласованы (например, просмотр, чтобы увидеть, есть ли данные в очереди, а затем вызов для получения данных только для того, чтобы обнаружить, что их больше нет).
person
Brad Wilson
schedule
22.10.2008
Обратите внимание: начиная с .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
Обратите внимание, что в версии документации .Net 4 для MessageQueue указано, что только GetAllMessages() является потокобезопасным. Я предполагаю, что это фактическое изменение, поскольку ошибочная документация, вероятно, была бы обновлена в соответствии с документацией .Net 4.
- person redcalx; 26.03.2012
Примечательно, что в моем модульном тесте было обнаружено, что метод Send() не является потокобезопасным, блокировка объекта MessageQueue разрешала различные исключения nullreference и т. д., которые возникали в моем параллельном цикле.
- person Kaido; 02.08.2013
@Kaido: Разблокированный
MessageQueue.Send()
привел к ошибкам? Или какое поведение вы испытали?
- person Dio F; 30.10.2013
Да, в коде платформы msft возникали исключения, когда я вызывал MessageQueue.Send() в одном экземпляре из нескольких потоков одновременно. Решено с помощью блокировки (myLockObj) {MessageQueue.Send();}
- person Kaido; 31.10.2013
Вас может заинтересовать запись в блоге, которую я написал на эту тему. .
Короче говоря, MSMQ C++ API является потокобезопасным, но не все методы System.Messaging являются потокобезопасными. В записи блога я обсуждаю, как вызывать MessageQueue.Send потокобезопасным способом.
person
Community
schedule
27.10.2008