Ниже приведен результат выполнения рассматриваемой здесь программы, хотя у вас он может оказаться несколько иным.
В потоке Событийный Поток 1
Событийный Поток 1
Основной поток ожидает событие.
Событийный Поток 1 Событийный Поток 1 Событийный Поток 1 Событийный Поток 1 Событийный Поток 1 завершен!
Основной поток получил уведомление о событии от первого потока.
В потоке Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 завершен!
Основной поток получил уведомление о событии от второго потока.
Прежде всего обратите внимание на то, что событие типаManualResetEventпередается непосредственно конструктору классаMyThread.Когда завершается методRun() из классаMyThread,он вызывает для событийного объекта методSet (),устанавливающий этот объект в сигнальное состояние. В методеMain() формируется событийный объектevtObjтипаManualResetEvent,первоначально устанавливаемый в исходное, несигнальное состояние. Затем создается экземпляр объекта типа
MyThread,которому передается событийный объектevtObj.После этого основной поток ожидает уведомления о событии. А поскольку событийный объектevtObjпервоначально находится в несигнальном состоянии, то основной поток вынужден ожидать до тех пор, пока для экземпляра объекта типаMyThreadне будет вызван методSet() ^устанавливающий событийный объектevtObjв сигнальное состояние. Это дает возможность основному потоку возобновить свое выполнение. Затем событийный объект устанавливается в исходное состояние, и весь процесс повторяется, но на этот раз для второго потока. Если бы не событийный объект, то все потоки выполнялись бы одновременно, а результаты их выполнения оказались бы окончательно запутанными. Для того чтобы убедиться в этом, попробуйте закомментировать вызов методаWaitOne () в методеMain ().
Если бы в рассматриваемой здесь программе событийный объект типаAutoResetEventиспользовался вместо событийного объекта типаManualResetEvent,то вызывать методReset() в методеMain() не пришлось бы. Ведь в этом случае событийный объект автоматически устанавливается в несигнальное состояние, когда поток, ожидающий данное событие, возобновляет свое выполнение. Для опробования этой разновидности события замените в данной программе все ссылки на объект типаManualResetEventссылками на объект типаAutoResetEventи удалите все вызовы методаReset (). Видоизмененная версия программы будет работать так же, как и прежде.
Класс Interlocked