Когда я буду использовать AutoResetEvent и ManualResetEvent вместо Monitor.Wait () / Monitor.Pulse ()? - PullRequest
20 голосов
/ 01 октября 2008

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

Ответы [ 4 ]

15 голосов
/ 01 октября 2008

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

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

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

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

10 голосов
/ 08 июля 2009

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

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

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

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

7 голосов
/ 12 марта 2012

Вы бы использовали 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 .

  • ManualResetEvent (или ManualResetEventSlim)
  • AutoResetEvent
  • Семафор (или SemaphoreSlim)
  • EventWaitHandle
  • CountdownEvent
  • Barrier

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

2 голосов
/ 01 октября 2008

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

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

и это будет охватывать ожидание / пульс: http://www.albahari.com/threading/part4.aspx#_Wait_and_Pulse

...