![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Использование TTimer
JaoDa © (2005-02-18 13:51:00)Копался в чужом коде и обнаружил такую строку:
TForm1.Timer1Timer(Sender: TObject);
begin
длительный процесс, превышающий время установленного интервала
end;
Обычно сам всегда делаю так:
TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled:=false;
длительный процесс, превышающий время установленного интервала
Timer1.Enabled:=true;
end;
Как правильно? не ведет ли первый способ к множественной попытке выполнения одних и тех же вычислений?
Alexander Panov (2005-02-18 14:59:00) [21]XP (18.02.05 14:57) [13]
А какие есть у Вас аргументы против использования, например, GOTO?
У меня против GOTO нет аргументов.
Если мне нужно будет - буду использовать.
XP (2005-02-18 14:57:00) [22]Можно пояснить, откуда такая информация?
Remarks
The DispatchMessage function forwards this message when no other messages are in the thread's message queue.
WM_TIMER + F1
повторное вхождение в процедуру обработки неизбежно.
При таком написании кода - да, неизбежно.
Но я уже сказал, что это грабли поставленные самому себе.
Ибо Timer + ProcessMessages + Sleep = гремучая смесь как с точки зрения логики, так и с точки зрения алгоритмического подхода. Это уже не винегрет програмный, а какая-то окрошка.
Нет, я не спорю, можно и не такое написать. Но думать-то при этом надо о последствиях.
аргументы?
А какие есть у Вас аргументы против использования, например, GOTO? Или Вы им все же пользуетесь?
Alexander Panov (2005-02-18 14:55:00) [23]Digitman © (18.02.05 14:51) [11]
Про цикл неправильно выразился-)
Если в приведенном коде
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: Integer;
begin
Memo1.Lines.Add(IntToStr(Tag));
Tag := Tag+1;
for i := 0 to 500 do
begin
Sleep(10);
Application.ProcessMessages;
end;
end;
заменить
for i := 0 to 500 doнаfor i := 0 to 5000000 do(Допустим) и убрать ProcessMessage, то в очереди сообщений за время работыforможет появиться(и появится) и обработаться следующее сообщение от таймера, что приведет к повторному входу в обработчик.
Digitman (2005-02-18 14:51:00) [24]
> Alexander Panov © (18.02.05 14:37) [7]
> Приведет. Если увеличишь значительно цикл.
Александр, ну в индейцы тебя отнюдь не зря в этом случае записали)
ты о каких "циклах"-то ? выборки/дисп-ции/обработки сообщений ? или о каких ?
Sandman25 (2005-02-18 14:49:00) [25]Допустим, таймер поставлен на 4 секунды.
Допустим, обработка таймера занимает 1 секунду.
Если я не выключу таймер в начале обработки, следующая обработка начнется через 4 секунды после начала предыдущей обработки.
А если выключу, то через 5 секунд после начала предыдущей обработки. Так?
Или же сообщение таймеру убирается из очереди только после завершения обработки, и поэтому в любом случае пройдет 5 секунд после начала предыдущей обработки?
Alexander Panov (2005-02-18 14:47:00) [26]XP (18.02.05 14:39) [8]
При помещении сообщения от таймера в очередь - производится поиск сообщений от этого же таймера в этой же очереди. При наличии такого сообщения, новое сообщение не добавляется.
Можно пояснить, откуда такая информация?
XP (18.02.05 14:39) [8]
P.S. Я все же надеюсь, что приведенный в [2] код - на самом деле приведен для того, чтобы показать, как не надо делать.
Нет, не для этого, а для того, чтобы показать, что повторное вхождение в процедуру обработки неизбежно.
Моветон?- аргументы?
XP (2005-02-18 14:39:00) [27]2 Alexander Panov
Только настоящий индеец может такое написать...
Эдак завтра рекурсивные конструкции объявите вне закона:
procedure DoSomething;
begin
if <SomeCondition> then
DoSomething;
end;
Кто же в обработчике событий таймера использует ProcessMessages таким образом? И вообще, ProcessMessages - la move ton. А особенно в обработчиках событий таймера.
Не доводите идею до абсурда!
Уж раз грабельки подложили, так хоть бы соломки подстелили.
2 JaoDa
При помещении сообщения от таймера в очередь - производится поиск сообщений от этого же таймера в этой же очереди. При наличии такого сообщения, новое сообщение не добавляется.
А то, что написал Александр - пример того, как не надо делать.
P.S. Я все же надеюсь, что приведенный в [2] код - на самом деле приведен для того, чтобы показать, как не надо делать.
Alexander Panov (2005-02-18 14:37:00) [28]BlackTr (18.02.05 14:36) [6]
Если убрать Application.ProcessMessages то не приведет к повторному входу
Приведет. Если увеличишь значительно цикл.
BlackTr (2005-02-18 14:36:00) [29]
> Вот я и привел иллючтрацию повторного входа в бработчик
> таймера в случае, если он не переводится в выключенное состояние.
Если убрать Application.ProcessMessages то не приведет к повторному входу
Alexander Panov (2005-02-18 14:32:00) [30]как японял автора, вопрос у него был таков, что если код в обработчике таймера занимает промежуток времени, превышающий интервал, то не ведет ли такая ситуация к повторному вхождению в эту процедуру...
Вот я и привел иллючтрацию повторного входа в бработчик таймера в случае, если он не переводится в выключенное состояние.
Digitman (2005-02-18 14:30:00) [31]
> Alexander Panov © (18.02.05 14:22) [2]
> Ведет
никто, в т.ч. и автор, не ограничивал меня в праве подразумевать нечто свое под выражением "одни и те же вычисления"
ШТАТНОЕ (т.е. ЯВНО и ОСОЗНАННО предусмотренное программистом) временное прерывание хода некоего блока вычислений в некоей точке ради потенциального выполнения того же блока вычислений (с возможно иными исх.параметрами), imho, никак нельзя назвать "ведущим к множественным попыткам" чего-то там ..
Alexander Panov (2005-02-18 14:23:00) [32]к [2] - интервал таймера - 1000
Alexander Panov (2005-02-18 14:22:00) [33]Digitman © (18.02.05 14:13) [1]
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: Integer;
begin
Memo1.Lines.Add(IntToStr(Tag));
Tag := Tag+1;
for i := 0 to 500 do
begin
Sleep(10);
Application.ProcessMessages;
end;
end;
JaoDa (18.02.05 13:51)
Как правильно? не ведет ли первый способ к множественной попытке выполнения одних и тех же вычислений?
Ведет. Пример см. выше.
Digitman (2005-02-18 14:13:00) [34]
> не ведет ли
в контексте одного и того же трэда, реагирующего на сообщения им же созданногго таймера - не ведет.
во втором же способе Timer1.Enabled:=false/true - как телеге пятое колесо