![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TTimer процедура обработки события таймера
ZV © (2010-09-09 17:01:00)Меня интересует такой вопрос - при входе в процедуру обработки события TTimer, таймер продолжает работать или нет? Не получиться такого что процедура обработки события еще не закончена а у таймера происходит новое событие. Или если я не уверен что процедура успеет выполнится до следующего события таймера то таймер лучше на время выполнения процедуры отключить?
Sha (2010-09-10 12:39:00) [1]> han_malign (10.09.10 12:07) [29]
> модальные окна делают тот самый ProcessMessage...
Конечно.
Но даже если об этом помнить, ProcessMessages может прятаться в чужих компонентах.
Можно организовать очередь команд или выкидывать параллельные команды:
var
Key: integer= 1;
procedure ExecuteCommand;
begin;
if InterlockedDecrement(Key)>=0 then begin;
DoExecute;
end;
InterlockedIncrement(Key);
end;
han_malign (2010-09-10 12:07:00) [2]
> ShowMessage ...
> Наверное, в их числе и сообщение от таймера обрабатывается.
- модальные окна делают тот самый ProcessMessage...
И. Павел (2010-09-10 11:45:00) [3]> [27] Sha © (10.09.10 10:01)
Интересный пример :)
Раз окошко в ShowMessage перерисовывается даже если после этого поставить sleep, значит он функцию прерывает и начинает принимать сообщения, т.е. цикл в Run возобновляется. Наверное, в их числе и сообщение от таймера обрабатывается.
Sha (2010-09-10 10:01:00) [4]> И. Павел © (10.09.10 08:36) [23]
Жми OK, через 10 сек посмотри в Memo1
var
FirstTime: dword= 0;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin;
if FirstTime=0 then begin;
FirstTime:=GetTickCount;
Randomize;
end
else if GetTickCount-FirstTime>10*1000 then exit;
for i:=0 to 99 do begin;
sleep(20);
if Random(40)=0 then ShowMessage('Press OK to continue');
Memo1.Lines.Add(IntToStr(i));
end;
end;
Ega23 (2010-09-10 09:51:00) [5]
> твой код принципиальноне верен :P :)
Это спорный вопрос.
Ega23 (2010-09-10 09:49:00) [6]
> Оба кода компилируются нормально.
Проверял?
И. Павел (2010-09-10 08:42:00) [7]> лн не выполнит.аллельно
он не выполнит. Параллельно
И. Павел (2010-09-10 08:36:00) [8]> при входе в процедуру обработки события TTimer, таймер продолжает
> работать или нет?
Пока главный поток не выйдет из этой процедуры, или не прервется на обработку других сообщений, ничего другого лн не выполнит.аллельно с ним могут выполняться только действия из других потоков. А таймер работает в главном потоке, так что если там нет ProcessMessage, то ИМХО, опасаться нечего.
Palladin (2010-09-10 07:56:00) [9]
> Ega23 © (10.09.10 01:01) [18]
твой код принципиальноне верен :P :)
каркас должен быть как минимум таким
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
try
... // обработка
except
if фатально then
raise;
end
Timer1.Enabled := True
end;
Anatoly Podgoretsky (2010-09-10 07:46:00) [10]> Юрий Зотов (09.09.2010 23:59:17) [17]
Ну да, например вызов знаменитого ProcessMessage, или косвенно через вызов
другой процедуры.
Германн (2010-09-10 02:23:00) [11]
> Ega23 © (10.09.10 01:01) [18]
>
> procedure TForm1.Timer1Timer(Sender: TObject);
> begin
> Timer1.Enabled := False;
> try
> ... // обработка
> finally
> Timer1.Enabled := True
> end
> end;
>
> > Олег! Я тобой горжусь! :o)
>
>
> Юрий Сергеич, спасибо!
> З.Ы. Мой код - компилируется.
> В отличие от. :))))
Оба кода компилируются нормально.
Не надо без излишней нужды выставлять себя "батонокидателем"!
:)
Даже в шутку. :)
Sha (2010-09-10 01:09:00) [12]> Anatoly Podgoretsky © (09.09.10 19:13) [15]
> Которое может возникнуть до окончания обработки
> Юрий Зотов © (09.09.10 23:59) [17]
> В однопоточной программе?
Юр, представь, что произойдет в случае [16]:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if IsDinnerTime then ShowMessage('Вам пора обедать. Хотите продолжить?');
ТутНезащищенныйЛритическойСекциейОченьКритическийКод
end;
Ega23 (2010-09-10 01:01:00) [13]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
try
... // обработка
finally
Timer1.Enabled := True
end
end;
> Олег! Я тобой горжусь! :o)
Юрий Сергеич, спасибо!
З.Ы. Мой код - компилируется.
В отличие от. :))))
Юрий Зотов (2010-09-09 23:59:00) [14]
> Anatoly Podgoretsky © (09.09.10 19:13) [15]
> Которое может возникнуть до окончания обработки
В однопоточной программе?
Sha (2010-09-09 22:45:00) [15]> Сергей М. © (09.09.10 17:41) [9]
> При возникновении очер.события таймера ОС прежде всего проверяет,
> нет ли уже в очереди сообщений целевому потоку сообщения WM_TIMER.
> Если нет, то ставит его в очередь, иначе "игнорирует" событие.
Это так. Но в неопытных руках и таймер стреляет:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
ShowMessage('Продолжить?');
end;
Anatoly Podgoretsky (2010-09-09 19:13:00) [16]
> Правда, выбрано из очереди и обработано оно будет только
> на следующем витке цикла выборки сообщений (то есть, после
> завершения обработки первого) - но все же оно будет выбрано
> и обработано.
Которое может возникнуть до окончания обработки и система пойдет вразнос.
Юрий Зотов (2010-09-09 18:41:00) [17]> сообщение OnTimer
сообщение WM_TIMER, конечно.
Юрий Зотов (2010-09-09 18:36:00) [18]
> ZV © (09.09.10 18:04) [11]
Когда сообщение WM_TIMER уже выбрано из очереди и выполняется (но еще не завершилась) обработка события OnTimer, ничто не мешает системе поставить в очередь еще одно сообщение OnTimer. Правда, выбрано из очереди и обработано оно будет только на следующем витке цикла выборки сообщений (то есть, после завершения обработки первого) - но все же оно будет выбрано и обработано.
Юрий Зотов (2010-09-09 18:30:00) [19]
> Palladin © (09.09.10 17:46) [10]
Может стоит, а может и нет - от задачи зависит. Не зная ее, сказать с уверенностью можно лишь одно - не стоит считать пример рабочим кодом.
:o)
ZV (2010-09-09 18:04:00) [20]
> Если нет, то ставит его в очередь, иначе "игнорирует" событие.
Спасибо . Теперь понятно как это работает. А я думал события становятся в очередь