M Y D E L P H I 7 . R U Самоучитель программирования  
 
  • Главная
  •  

     

    Событие

    Объект типа событие (event) — простейший выбор для задач синхронизации. Он подобен дверному звонку — звенит до тех пор, пока его кнопка находится в нажатом состоянии, извещая об этом факте окружающих. Аналогично, и объект может быть в двух состояниях, а "слышать" его могут многие потоки сразу.

    Класс TEvent (модуль SYNCOBJS.PAS) имеет два метода: setEvent и ResetEvent, которые переводят объект в активное и пассивное состояние соответственно. Конструктор имеет следующий вид:

    constructor Create(EventAttributes: PSecurityAttributes; 

    ManualReset, InitialState: Boolean; const Name: string);

    Здесь параметр initialstate — начальное состояние объекта, ManualReset — способ его сброса (перевода в пассивное состояние). Если этот параметр равен True, событие должно быть сброшено вручную. В противном случае событие сбрасывается по мере того, как стартует хоть один поток, ждавший данный объект.

    На третьем методе:

    TWaitResult = (wrSignaled, wrTimeout, wrAbandoned, wrError); 

    function WaitFor(Timeout: DWORD): TWaitResult;

    остановимся подробнее. Он дает возможность ожидать активизации события в течение Timeout миллисекунд. Как вы могли догадаться, внутри этого метода происходит вызов функции waitFotsingieObject. Типичных результатов на выходе waitFor два — wrsignaied, если произошла активизация события, и wrTimeout, если за время тайм-аута ничего не произошло.

    Примечание 

    Если нужно (и допустимо!) ждать бесконечно долго, следует установить параметр Timeout в значение INFINITE.

    Рассмотрим маленький пример. Включим в состав нового проекта объект типа TThread, наполнив его метод Execute следующим содержимым:

    Var res: TWaitResult;

    procedure TSimpleThread.Execute;

    begin

    e := TEvent.Create(nil,True,false, 'test');

    repeat

    e.ReSetEvent;

    res := e.WaitFor(10000);

    Synchronize(Showlnfo);

    until Terminated; e.Free; 

    end;

    procedure TSimpleThread.Showlnfo;

    begin

    ShowMessage(IntToStr(Integer (res)));

    end;

    На главной форме разместим две кнопки — нажатие одной из них запускает поток, нажатие второй активизирует событие:

    procedure TForml.ButtonlClick(Sender: TObject);

    begin

    TSimpleThread.Create(False); 

    end;

    procedure TForml.Button2Click(Sender: TObject);

    begin

    e.SetEvent; 

    end;

    Нажмем первую кнопку. Тогда появившийся на экране результат (метод Showlnfo) будет зависеть от того, была ли нажата вторая кнопка или истекли отведенные 10 секунд.

    События используются не только для работы с потоками — некоторые процедуры операционной системы автоматически переключают их. К числу

    таких процедур относятся отложенный (overlapped) ввод/вывод и события, связанные с коммуникационными портами.