Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.09.2014, 04:50   #1
xexxex
Пользователь
 
Регистрация: 31.07.2010
Сообщений: 52
По умолчанию TTimer

Вот если я нахожусь внутри события OnTimer и заковырялся там, может ли случиться очередное событие OnTimer , пока я там нахожусь внутри. Или внутри при входе отключать таймер, а при выходе включать?
xexxex вне форума Ответить с цитированием
Старый 04.09.2014, 05:23   #2
Vad33
Участник клуба
 
Аватар для Vad33
 
Регистрация: 24.07.2009
Сообщений: 638
По умолчанию

Цитата:
Сообщение от xexxex Посмотреть сообщение
Вот если я нахожусь внутри события OnTimer и заковырялся там, может ли случиться очередное событие OnTimer , пока я там нахожусь внутри. Или внутри при входе отключать таймер, а при выходе включать?
Да, нужно выключать.
** Удача терпелива. **
Vad3333@inbox.ru
Vad33 вне форума Ответить с цитированием
Старый 04.09.2014, 08:00   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Да, нужно выключать.
Ну не то чтобы обязательно нужно, но да - это, скажем так, может предотвратить некоторые неожиданности.
А вообще чтоб окончательно избежать такой проблемы лучше использовать Thread а не таймер.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 04.09.2014, 08:14   #4
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Ничего выключать не надо!!!
Таймер повторно не сработает.
Объясняю:
Таймер - событие и выполняется в потоке выборки сообщений. Пока поток занят выполнением таймерной процедуры, пока принудительно не вызываются ProcessMessages - процедура таймера параллельно предыдущей не запустится, поток то один. Да события/месаджи могут нападать в очередь, но они встанут в очередь и будут ждать пока поток не вернется к разгребанию очереди. Да процедура таймера может сработать раньше чем указано в интервале, а может и позже т.к. таймер имеет низкий событийный приоритет
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 04.09.2014, 08:50   #5
Vad33
Участник клуба
 
Аватар для Vad33
 
Регистрация: 24.07.2009
Сообщений: 638
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
Ничего выключать не надо!!!...
Ну то есть вешаем на срабатывание таймера например
такую процедурку:
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
 Application.MessageBox('АХТУНГ','!!!!',MB_OK+MB_ICONERROR);
end;
и радуемся результату в быстром нажимании кнопки?
Не стоит изначально подкладывать себе мины.
** Удача терпелива. **
Vad3333@inbox.ru

Последний раз редактировалось Vad33; 04.09.2014 в 08:55.
Vad33 вне форума Ответить с цитированием
Старый 04.09.2014, 09:16   #6
IliaIT
Форумчанин
 
Аватар для IliaIT
 
Регистрация: 17.03.2009
Сообщений: 977
По умолчанию

и где пример что заковырялся в таймере? ваша процедура выполняется быстро, таймер не будет ждать получения ответа от кнопки, это не его задача. вот если бы вы поручили цикл до миллиона раз вычисления числа пи и ещё чего то что нагрузит проц то таймер вызовет тормоза программы. и второй раз пока не завершит не будет выполнятся. потому и рекомендуют использовать потоки что бы основная прога не висла во время обработки.
Интуитивно понятный интерфейс - это такой интерфейс, для работы с которым нужна недюжинная интуиция.
IliaIT вне форума Ответить с цитированием
Старый 04.09.2014, 09:22   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Slym, Вы заблуждаетесь.
При чём здесь очередь сообщений Windows и процедура в Delphi ?!
Неужели трудно написать простейший код и ПРОВЕРИТЬ то, что Вы утверждаете?!

я сделал это за Вас.
Экспериментируйте:
EXE-шник: Project1EXE.rar
Исходники: Project1Src.rar



А по сути вопроса.
Я лично в подобных случаях, когда возможно срабатывание следующего тика таймера до выхода из текущего, просто использую булевую переменную.
вначале переменная isInTimer := false
Зашли в процедуру таймера, проверили переменную, если она True - сразу вышли.
иначе поставили isInTimer := true
выполнили нужные действия.
при выходе из таймера сделали isInTimer := false

всё. повторные срабатывания нас больше не беспокоят.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 04.09.2014, 09:26   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
таймер не будет ждать получения ответа от кнопки
Чего не будет? Конкретный тик будет, с каких пор MessageBox асинхронной стало? Другое дело, что такую лободу не чего в таймер сувать, еще бы форматирование диска туда, ага
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 04.09.2014 в 09:33.
Аватар вне форума Ответить с цитированием
Старый 04.09.2014, 10:09   #9
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Slym, Вы заблуждаетесь.
При чём здесь очередь сообщений Windows и процедура в Delphi ?!
Неужели трудно написать простейший код и ПРОВЕРИТЬ то, что Вы утверждаете?!
1. А при том! Неужели трудно посмотреть генофонд
таймер это сообщение WM_TIMER
Код:
procedure TTimer.WndProc(var Msg: TMessage);
begin
  with Msg do
    if Msg = WM_TIMER then
      try
        Timer;
      except
        Application.HandleException(Self);
      end
    else
      Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;
2. В вашем коде рекурсия! собработчик таймера запускает обработчик таймера посредством ProcessMessages
3. Я четко указал что параллельно (а в нашем контексте одновременно) таймер не запустится, без вызова ProcessMessages или процедур вызывающих ее аналоги к коим относится MessageBox
т.е. MessageBox можно представить в виде
Код:
procedure MessageBoxProc;
begin
  while True do Application.ProcessMessages;
end;
4. и кстати что ваш пример доказывает? то что не рекомендуется ProcessMessages в таймере вызывать или MessageBox?
5. Мой пример.
если таймер <1500мс то срабатывать об будет сразу, но не параллельно, как только закончится предыдущий, т.к. событие уже в очереди
Вложения
Тип файла: rar Project1Src.rar (2.2 Кб, 10 просмотров)
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 04.09.2014 в 10:21.
Slym вне форума Ответить с цитированием
Старый 04.09.2014, 11:03   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
В вашем коде рекурсия! собработчик таймера запускает обработчик таймера посредством ProcessMessages
почитайте, что такое рекурсия. Тут есть вызов процедурой самой себя?!

С тем, что я разрешаю оконному обработчику разобрать накопившуюся очередь сообщений, в том числе, среди прочих событий разрешаю вызвать процедуру таймера, - с этим я согласен. Да, это так.

Цитата:
и кстати что ваш пример доказывает? то что не рекомендуется ProcessMessages в таймере вызывать
ProcessMessages нужно вызывать в ЛЮБОМ долгом цикле, иначе форма у вас не будет отвечать операционке. Поэтому, если у Вас есть длительная обработка в цикле (не важно, на таймере или нет), то нужно использовать ProcessMessages, обрабатывать очередь сообщений. Иначе ничего на форме работать не будет, пока цикл выполняется.


Цитата:
если таймер <1500мс то срабатывать об будет сразу, но не параллельно, как только закончится предыдущий, т.к. событие уже в очереди
можно было не выкладывать исходник. достаточно было сказать, что Вы в цикле заменили Application.ProcessMessages() на Sleep(10):
Код:
  CountTicks := GetTickCount();
  repeat
    // Application.ProcessMessages()
    sleep(10);
  until GetTickCount()>= (CountTicks+1500);
ну и ваш пример убедительно показывает, что так делать НЕЛЬЗЯ.

поставьте время работы процедуры побольше, просто для наглядности, ну, например,
Код:
  CountTicks := GetTickCount();
  repeat
    // Application.ProcessMessages()
    sleep(10);
  until GetTickCount()>= (CountTicks+15000);  {15 секунд}
дождитесь, когда таймер сработает:
" таймер сработал в ...."
а теперь попробуйте изменить время, или нажать на кнопку "Stop timer"
или хотя бы, банально, форму по экрану подвигать.
Не получается?! Вот именно!
Это убедительно доказывает, что так, как Вы предлагаете (не использовать ProcessMessages) программировать нельзя!

впрочем. Вы понимаете, о чём я пишу. Я понимаю, о чём Вы пишете.
Думаю, что вопрос исчерапан, sapienti sat.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Компонент TTimer viks1 Общие вопросы Delphi 5 14.05.2012 19:56
TTimer Китос Общие вопросы Delphi 5 24.09.2011 19:03
TTimer ak3000 Компоненты Delphi 9 14.11.2008 18:18
TTimer в Delphi AlexandrSid Общие вопросы Delphi 7 23.05.2008 14:10
TTimer amandra Компоненты Delphi 3 19.11.2007 13:54