Когда мне следует использовать AutoResetEvent и ManualResetEvent вместо Monitor.Wait()/Monitor.Pulse()?

StackOverflow https://stackoverflow.com/questions/158133

Вопрос

Кажется, они оба преследуют одну и ту же цель.Когда бы я предпочел один другому?

Это было полезно?

Решение

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

Используйте монитор, если вы хотите ограничить доступ к структуре данных, ограничив количество потоков, которые могут получить к ней доступ.

Мониторы обычно защищают ресурс, тогда как события сообщают вам, что что-то происходит, например, закрытие приложения.

Также событиям можно давать имена (см. метод OpenExisting), это позволяет использовать их для синхронизации между разными процессами.

Другие советы

На мой взгляд, лучше использовать Monitor, если можете. Monitor.Wait и Monitor.Pulse/PulseAll используются для сигнализации между потоками (как и Manual/AutoResetEvent), однако Monitor работает быстрее и не использует собственный системный ресурс.Также очевидно, что Monitor реализован в пользовательском режиме и управляется, тогда как Manual/AutoResetEvents требует переключения в режим ядра и p/invoke для собственных вызовов Win32, которые используют дескриптор ожидания.

Бывают ситуации, когда вам нужно будет использовать Manual/AutoResetEvent, например, для сигнализации между процессами, вы можете использовать именованные события, и, я думаю, для сигнализации собственных потоков в вашем приложении.

Я просто повторяю то, что прочитал эта превосходная статья о резьбе.

Стоит прочитать всю статью, однако ссылка приведет вас к разделу дескриптора ожидания, в котором подробно описываются события и отслеживается ожидание/импульс.

Вы бы использовали WaitHandle когда вы хотите, чтобы поток отправлял или получал двоичный сигнал без необходимость критического раздела. Monitor.Wait и Monitor.Pulse с другой стороны требовать критический раздел.Как и большинство механизмов синхронизации в BCL, способы использования упомянутых вами двух механизмов частично совпадают.Но ни на секунду не думайте, что они выполняют одну и ту же цель.

Monitor.Wait и Monitor.Pulse представляют собой гораздо более примитивный механизм синхронизации, чем MRE или ARE.Фактически, вы можете построить MRE или ARE, используя только Monitor сорт.Самая важная концепция, которую необходимо понять, заключается в том, как Monitor.Wait и WaitHandle.WaitOne методы различаются. Wait и WaitOne оба поместят нить в WaitSleepJoin состояние, которое означает, что поток простаивает и отвечает только на Thread.Interrupt или соответствующий Pulse или Set вызов.Но, и это главное отличие, Wait покинет критическую секцию и заберет ее снова атомарным способом. WaitOne просто не может этого сделать.Это настолько фундаментальное различие в поведении этих механизмов синхронизации, что оно определяет сценарии, в которых они могут использоваться.

В большинстве ситуаций вы бы выбрали MRE или ARE.Они удовлетворяют большинству ситуаций, когда одному потоку необходимо получить сигнал от другого.Однако, если вы хотите создать свой собственный механизм сигнализации, вам нужно будет использовать Wait и Pulse.Но, опять же, в .NET BCL уже реализовано большинство популярных механизмов сигнализации.Следующие сигнальные механизмы уже существуют1.

  • Мануалресетевент (или мануалресетевентслим)
  • AutoResetEvent
  • Семафор (или SemaphoreSlim)
  • СобытиеWaitHandle
  • Событие обратного отсчета
  • Барьер

1Почетное упоминание достаётся BlockingCollection сорт.Это не механизм сигнализации как таковой, но он обладает качествами механизма сигнализации с дополнительным преимуществом, заключающимся в том, что к сигналу можно прикреплять данные.В этом случае сигнал означает, что элемент доступен в коллекции, а данные, связанные с этим сигналом, являются самим элементом.

В этом руководстве подробно описано, что вам нужно знать:http://www.albahari.com/threading/

В частности, это будет охватывать классы XXXResetEvent,
http://www.albahari.com/threading/part2.aspx

и это будет охватывать Wait/Pulse:http://www.albahari.com/threading/part4.aspx#_Wait_and_Pulse

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top