Форум: "Начинающим";
Текущий архив: 2010.11.28;
Скачать: [xml.tar.bz2];
ВнизTTimer процедура обработки события таймера Найти похожие ветки
← →
ZV © (2010-09-09 17:01) [0]Меня интересует такой вопрос - при входе в процедуру обработки события TTimer, таймер продолжает работать или нет? Не получиться такого что процедура обработки события еще не закончена а у таймера происходит новое событие. Или если я не уверен что процедура успеет выполнится до следующего события таймера то таймер лучше на время выполнения процедуры отключить?
← →
Сергей М. © (2010-09-09 17:12) [1]
> при входе в процедуру обработки события TTimer, таймер продолжает
> работать или нет?
Продолжает.
> Не получиться такого что процедура обработки события еще
> не закончена а у таймера происходит новое событие
Не получится.
← →
ZV © (2010-09-09 17:18) [2]Получается какие то противоречия. Значит таймер продолжает работать а событие не происходит ? Или происходит но обработчик не запустится пока не закончится обработка предыдущего события?
← →
Сергей М. © (2010-09-09 17:23) [3]
> Или происходит но обработчик не запустится пока не закончится
> обработка предыдущего события?
Именно так.
← →
ZV © (2010-09-09 17:29) [4]Получается происходит буферизация событий, а мне так не надо, если не успел обработать новое событие то и хрен с ним главное старое закончить, ведь так в очередь могут стать фиг его знает сколько событий.
Я так думаю на время выполнения процедуры обработки события таймер надо отключать?
← →
Ega23 © (2010-09-09 17:34) [5]
> Получается происходит буферизация событий, а мне так не
> надо, если не успел обработать новое событие то и хрен с
> ним главное старое закончить, ведь так в очередь могут стать
> фиг его знает сколько событий.procedure TForm1.Timer1OnTimer(Sender: TObject);
begin
Timer1.Enabled := False;
try
// Делаем что надо
finally
Timer1.Enabled := True;
end;
end;
← →
Юрий Зотов © (2010-09-09 17:37) [6]> ZV © (09.09.10 17:29) [4]
Или отключать:procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
try
... // обработка
finally
Timer1.Enabled := True
end
end;
Или вводить в форму приватное булевское поле FBusy:procedure TForm1.Timer1Timer(Sender: TObject);
begin
if FBusy then
Exit;
FBusy := True;
try
... // обработка
finally
FBusy := False
end
end;
← →
Юрий Зотов © (2010-09-09 17:38) [7]
> Ega23 © (09.09.10 17:34) [5]
Олег! Я тобой горжусь!
:o)
← →
ZV © (2010-09-09 17:41) [8]Все понял, спасибо.
← →
Сергей М. © (2010-09-09 17:41) [9]
> ведь так в очередь могут стать фиг его знает сколько событий
Ничего подобного.
При возникновении очер.события таймера ОС прежде всего проверяет, нет ли уже в очереди сообщений целевому потоку сообщения WM_TIMER.
Если нет, то ставит его в очередь, иначе "игнорирует" событие.
← →
Palladin © (2010-09-09 17:46) [10]
> try ... // обработка
> finally Timer1.Enabled := True
> end
категорисески не согласен... ) а стоит ли продолжать если эксцепшн?
← →
ZV © (2010-09-09 18:04) [11]
> Если нет, то ставит его в очередь, иначе "игнорирует" событие.
Спасибо . Теперь понятно как это работает. А я думал события становятся в очередь
← →
Юрий Зотов © (2010-09-09 18:30) [12]
> Palladin © (09.09.10 17:46) [10]
Может стоит, а может и нет - от задачи зависит. Не зная ее, сказать с уверенностью можно лишь одно - не стоит считать пример рабочим кодом.
:o)
← →
Юрий Зотов © (2010-09-09 18:36) [13]
> ZV © (09.09.10 18:04) [11]
Когда сообщение WM_TIMER уже выбрано из очереди и выполняется (но еще не завершилась) обработка события OnTimer, ничто не мешает системе поставить в очередь еще одно сообщение OnTimer. Правда, выбрано из очереди и обработано оно будет только на следующем витке цикла выборки сообщений (то есть, после завершения обработки первого) - но все же оно будет выбрано и обработано.
← →
Юрий Зотов © (2010-09-09 18:41) [14]> сообщение OnTimer
сообщение WM_TIMER, конечно.
← →
Anatoly Podgoretsky © (2010-09-09 19:13) [15]
> Правда, выбрано из очереди и обработано оно будет только
> на следующем витке цикла выборки сообщений (то есть, после
> завершения обработки первого) - но все же оно будет выбрано
> и обработано.
Которое может возникнуть до окончания обработки и система пойдет вразнос.
← →
Sha © (2010-09-09 22:45) [16]> Сергей М. © (09.09.10 17:41) [9]
> При возникновении очер.события таймера ОС прежде всего проверяет,
> нет ли уже в очереди сообщений целевому потоку сообщения WM_TIMER.
> Если нет, то ставит его в очередь, иначе "игнорирует" событие.
Это так. Но в неопытных руках и таймер стреляет:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
ShowMessage("Продолжить?");
end;
← →
Юрий Зотов © (2010-09-09 23:59) [17]
> Anatoly Podgoretsky © (09.09.10 19:13) [15]
> Которое может возникнуть до окончания обработки
В однопоточной программе?
← →
Ega23 © (2010-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) [19]> 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;
← →
Германн © (2010-09-10 02:23) [20]
> Ega23 © (10.09.10 01:01) [18]
>
> procedure TForm1.Timer1Timer(Sender: TObject);
> begin
> Timer1.Enabled := False;
> try
> ... // обработка
> finally
> Timer1.Enabled := True
> end
> end;
>
> > Олег! Я тобой горжусь! :o)
>
>
> Юрий Сергеич, спасибо!
> З.Ы. Мой код - компилируется.
> В отличие от. :))))
Оба кода компилируются нормально.
Не надо без излишней нужды выставлять себя "батонокидателем"!
:)
Даже в шутку. :)
← →
Anatoly Podgoretsky © (2010-09-10 07:46) [21]> Юрий Зотов (09.09.2010 23:59:17) [17]
Ну да, например вызов знаменитого ProcessMessage, или косвенно через вызов
другой процедуры.
← →
Palladin © (2010-09-10 07:56) [22]
> 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;
← →
И. Павел © (2010-09-10 08:36) [23]> при входе в процедуру обработки события TTimer, таймер продолжает
> работать или нет?
Пока главный поток не выйдет из этой процедуры, или не прервется на обработку других сообщений, ничего другого лн не выполнит.аллельно с ним могут выполняться только действия из других потоков. А таймер работает в главном потоке, так что если там нет ProcessMessage, то ИМХО, опасаться нечего.
← →
И. Павел © (2010-09-10 08:42) [24]> лн не выполнит.аллельно
он не выполнит. Параллельно
← →
Ega23 © (2010-09-10 09:49) [25]
> Оба кода компилируются нормально.
Проверял?
← →
Ega23 © (2010-09-10 09:51) [26]
> твой код принципиальноне верен :P :)
Это спорный вопрос.
← →
Sha © (2010-09-10 10:01) [27]> И. Павел © (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;
← →
И. Павел © (2010-09-10 11:45) [28]> [27] Sha © (10.09.10 10:01)
Интересный пример :)
Раз окошко в ShowMessage перерисовывается даже если после этого поставить sleep, значит он функцию прерывает и начинает принимать сообщения, т.е. цикл в Run возобновляется. Наверное, в их числе и сообщение от таймера обрабатывается.
← →
han_malign (2010-09-10 12:07) [29]
> ShowMessage ...
> Наверное, в их числе и сообщение от таймера обрабатывается.
- модальные окна делают тот самый ProcessMessage...
← →
Sha © (2010-09-10 12:39) [30]> 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;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.11.28;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.009 c