Delphi. Потоки. События (Tevent)

В данной статье я разбирался с тем как работают события (TEvent) в потоках. Составил небольшой пример. Кроме главного, будут работать 2 потока. Один будет заполнять ProgressBar. Другой пытаться получить значение ProgressBar.Position и вывести его в заголовок формы. Естественно, пока работает первый поток — это у него не получится. Он будет ожидать результата до конца работы первого потока. Форма будет выглядеть следующим образом.

19

Описание кода

В uses добавим syncobjs

Cоздадим классы 2 потоков

Создадим в глобальных переменных имена для 2 экземпляров потоков, а также переменную события

Создадим Event и уничтожим его в соответствующих событиях формы

Уничтожение Event

Теперь обработаем execute первого потока

Execute 2 потока

Вызов первого потока

Вызов второго потока

Результат

При нажатии на Start

20

При нажатии на GetProgressPosition во время выполнения потока 1

21

После завершения потока 1

22

Первое общее впечатление от работы с TEvent — чем-то напомнило работу критических секций с одной стороны — то есть на время выполнения первым потоком своего участка кода доступ к ProgressBar был закрыт.

С другой стороны мы использовали метод WaitFor, его перегруженную версию, который также есть у потоков. Но у потоков у нас только один вариант — дождаться конца исполнения. Так как согласно документации метод определен следующим образом

А у TEvent этот же метод определен вот так

Поэтому мы могли использовать конструкцию, вроде

То есть заглянули в событие на 250 милисек. и проверили — занят ли поток событием. То есть, если событие в сигнальном состоянии (wrSignaled), тогда участок кода между

свободен для другого потока. А если в несигнальном(<>wrSignaled) — то тогда другой поток не может обратиться к этому участку кода.

Я бы сказал, что этот инструмент сочетает в себе возможности критических секций с одной стороны и некоторых методов потоков с другой (WaitFor). Очень, очень удобно для организации доступа к совместным ресурсам.