|
Вопрос # 3 237/ вопрос решён / |
|
Приветствую, уважаемые эксперты!
Прошу подсказать, как реализовать аналог TTimer в консольном приложении (без создания форм).
Т.е. по истечении заданного времени он должен вызывать заданную процедуру. Однако, до истечения этого времени должен выполняться основной цикл программы.
Пробовал использовать системную функцию Now и высчитывать нужное время, но в результате программа "подтормаживает" машину.
Пробовал задавать
TimHandler:=SetTimer(0,0,interval, @Func);
Ошибок компиляции нет,
TimHandler ненулевой, однако по истечении времени interval
вызов процедуры Func не происходит.
 |
Вопрос задал: alexandergb (статус: Посетитель)
Вопрос отправлен: 29 сентября 2009, 18:06
Состояние вопроса: решён, ответов: 2.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, alexandergb!
Обычный TTimer работает через функцию SetTimer. А эта функция не может работать, если нет окна (Windows посылает сообщения WM_TIMER окну, которое и вызывает обработчик).
Считать время через главный цикл можно, просто наверно захотелось очень большую точность и сделали слишком маленький шаг квантования (опроса). В данном случае наиболее красивым вариантом будет использование треда (он же поток, он же TThread). Вот только нельзя использовать OnTerminate и Synhronyze (ой, или как он там) - они оба работают через посылку сообщения.
Если процедуру надо просто выполнить - тред может взять и выполнить её. Правда не надо забывать о синхронизации, потому что она будет выполняться ПАРАЛЛЕЛЬНО. для этого наиболее просто использовать критические секции (гуглим по слову TCriticalSection).
Ну а задержка реализуется банальным sleep(секунд). Торомозов она никаких не внесёт. (выполнение sleep в треде практически не дает накладных расходов. планировщик процессов, который переключает треды, видит, что поток отмечет как спящий, проверяет его время и идет дальше).
Если же надо периодически выполнять код - просто ставим цикл while. Но только надо помнить, что теперь весь цикл будет иметь длину чуть больше, чем sleep - код тоже имеет время выполнения. Поэтому лучше будет запоминать время просыпания и рассчитывать необходимое время для "сна".
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 29 сентября 2009, 18:21
Оценка за ответ: 5
|
Ответ #2. Отвечает эксперт: min@y™
Если приложение консольное, то нужно вручную создать окно и его оконную процедуру, чтобы принимать и обрабатывать сообщения WM_TIMER. Для того, чтобы это сообщение приходило от ядра системы, надо воспользоваться функцией SetTimer().
Могу попробовать написать такую вещь, если сам не разберёшься, однако, я думаю, что ты тут напишешь: "попробовал, не получилось, помогите!", т.е. захочешь, шоп я это всё сделал за тебя. Так не пойдёт! Предъявить будешь обязан код свой, падаван, да прибудет с тобой сила. © :)
 |
Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 29 сентября 2009, 19:11
Оценка за ответ: 5
|
Мини-форум вопроса
Всего сообщений: 0.
31 января 2011, 19:36: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|