Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.11.28;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.012 c
2-1283771755
rnts
2010-09-06 15:15
2010.11.28
Ошибка в запросе


2-1283688884
nubik
2010-09-05 16:14
2010.11.28
Как вывести в сообщении знак


15-1282465841
AlexDn
2010-08-22 12:30
2010.11.28
Просветите насчет имени


15-1282217798
Василий Жогарев
2010-08-19 15:36
2010.11.28
ActionManager & ActionMainMenuBar


2-1283158922
azamatufa
2010-08-30 13:02
2010.11.28
Что лучше использовать BDE или ADO ?