Страница 407 из 502
Ниже приведены общие формы методов Pulse() и PulseAll():
<b>public static void Pulse(object obj)</b>
<b>public static void PulseAll(object obj)</b>
где obj обозначает освобождаемый объект.
Если методы Wait(),Pulse() и PulseAll() вызываются из кода, находящегося за пределами синхронизированного кода, например из блока lock, то генерируется исключение SynchronizationLockException.
Для того чтобы стало понятнее назначение методов Wait() и Pulse(), рассмотрим пример программы, имитирующей тиканье часов и отображающей этот процесс на экране словами "тик" и "так". Для этой цели в программе создается класс TickTock, содержащий два следующих метода: Tick() и Тоск(). Метод Tick() выводит на экран слово "тик", а метод Тоск() — слово "так". Для запуска часов далее в программе создаются два потока: один из них вызывает метод Tick(), а другой — метод Тоск(). Преследуемая в данном случае цель состоит в том, чтобы оба потока выполнялись, поочередно выводя на экран слова "тик" и "так", из которых образуется повторяющийся ряд "тик-так", имитирующий ход часов.
<b>//Использовать методы Wait() и Pulse() для иммитации</b>
<b>//тиканья часов</b>
<b>using System;</b>
<b>using System.Threading;</b>
<b>class TickTock {</b>
<b> object lockOn = new object();</b>
<b> public void Tick(bool ru
<b> lock(lockOn) {</b>
<b> if(!ru
<b> Monitor.Pulse(lockOn); // уведомить любые ожидающие потоки</b>
<b> return;</b>
<b> }</b>
<b> Console.Write("тик ");</b>
<b> Monitor.Pulse(lockOn); // разрешить выполнение метода Tock()</b>
<b> Monitor.Wait(lockOn); // ожидать завершения метода Tock()</b>
<b> }</b>
<b> }</b>
<b> public void Tock(bool ru
<b> lock(lockOn) {</b>
<b> if(!ru
<b> Monitor.Pulse(lockOn); // уведомить любые ожидающие потоки </b>
<b> return;</b>
<b> }</b>
<b> Console.WriteLine("так");</b>
<b> Monitor.Pulse(lockOn); // разрешить выполнение метода Tick()</b>
<b> Monitor.Wait(lockOn); // ожидать завершения метода Tick()</b>
<b> }</b>
<b> }</b>
<b>}</b>
<b>class MyThread {</b>
<b> public Thread Thrd;</b>
<b> TickTock ttOb;</b>
<b> // Сконструировать новый поток.</b>
<b> public MyThread(string name, TickTock tt) {</b>
<b> Thrd = new Thread(this.Run);</b>
<b> ttOb = tt;</b>
<b> Thrd.Name = name;</b>
<b> Thrd.Start();</b>
<b> }</b>
<b> // Начать выполнение нового потока,</b>
<b> void Run() {</b>
<b> if(Thrd.Name == "Tick") {</b>
<b> for(int i=0; i<5; i++)</b>
<b> ttOb.Tick(true);</b>
<b> ttOb.Tick(false) ;</b>
<b> }</b>
<b> else {</b>
<b> for(int i=0; i<5; i++)</b>
<b> ttOb.Tock(true);</b>
<b> ttOb.Tock(false);</b>
<b> }</b>
<b> }</b>
<b>}</b>
<b>class TickingClock {</b>
<b> static void Main() {</b>
<b> TickTock tt = new TickTock();</b>
<b> MyThread mt1 = new MyThread("Tick", tt);</b>
<b> MyThread mt2 = new MyThread("Tock", tt);</b>