![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с таймером
mr. Eof © (2008-03-10 23:22:00)Здравствуйте.
Подскажите, как можно запускать в программе выполнение функций по истечению определенного врмени?
Тоесть, мне надо выполнять набор неких действий каждые 10 секунд.
!!! Использовать стандартный компонент таймер я не могу !!!
Я пытался так:
program time;
{$APPTYPE CONSOLE}
//---------------------------------------------
uses Windows, SysUtils, Messages;
//---------------------------------------------
var
Hour1,Min1,Sec1,Hour2,Min2,Sec2: integer;
Time1,Time2: SystemTime;
//---------------------------------------------
begin
while True do
begin
GetLocalTime(Time1);
Hour1:= Time1.wHour;
Min1:= Time1.wMinute;
Sec1:= Time1.wSecond;
while True do
begin
GetLocalTime(Time2);
Sec2:= Time2.wSecond;
if (Sec1+10 = Sec2) then
begin
writeln(inttostr(Hour1)+':'+inttostr(Min1)+':'+inttostr(Sec1));
break;
end;
end;
end;
end.
Данный вариант бесспорно хорош)), однако грузит процессор под 100% и тд...
Подскаите выход?
Германн (2008-03-13 00:57:00) [1]
> В консоли я тестирую, так как похоже.
А что мешает тестировать в сервисе?
P.S. А вот использовать разные ники в одной ветке некошерно. Можешь огрести за нарушение правил форума.
Dm1tr1y (2008-03-12 19:50:00) [2]Да, до этого приложение было консольным и запускалось по требованию пользователя, вручную.
Dm1tr1y (2008-03-12 19:49:00) [3]Сервис. Результат - dll.
В консоли я тестирую, так как похоже.
По поводу Application.ProcessMessages - да, не подойдет. Я не заметил сразу :)
DVM (2008-03-12 13:45:00) [4]
> и одним из требований является постоянная работа сервиса.
> .
Так сервис или консольное приложение? Пока что сервисами в примерах выше и не пахнет.
Leonid Troyanovsky (2008-03-12 13:37:00) [5]
> mr. Eof (11.03.08 23:38) [20]
> Я правильно понимаю, что имеется ввиду это:
Только не это :)
Или два потока в консоли, или GUI приложение (да хотя бы и сервис)
с окном верхнего уровня.
--
Regards, LVT.
Сергей М. (2008-03-12 08:31:00) [6]
> постоянная работа сервиса
А до постановки задачи она, надо понимать, непостоянная ?
И как же эта "непостоянность" проявляется ?
> lBusy := MsgWaitForMultipleObjects(1, hTimer, False,
> INFINITE, QS_ALLINPUT);
> Application.ProcessMessages;
Какой еще Application ?
У тебя же консольное приложение, судя по приведенному коду, не использует VCL ?..
mr. Eof (2008-03-12 00:17:00) [7]
> А что в конечном результате ты хочешь сделать? А т не очень
> понятны все эти пляски с таймерами и задержками.
DVM, в данном случае это не принципиально. Руководство поставило задачу модифицировать существующее приложение, и одним из требований является постоянная работа сервиса..
Я сделал это используя sleep и на 1й взгляд все норм работает.
Однако после сообщений Leonid Troyanovsky, я сильно засомневался...
DVM (2008-03-11 23:48:00) [8]
> mr. Eof
А что в конечном результате ты хочешь сделать? А т не очень понятны все эти пляски с таймерами и задержками.
mr. Eof (2008-03-11 23:38:00) [9]
> Резюме: или делать в консоли второй поток с Waitable Timer
Я правильно понимаю, что имеется ввиду это:
procedure Wait(lNumberOfSeconds : Longint);
const
_SECOND = 10000000;
var
lBusy : LongInt;
hTimer : LongInt;
liDueTime : LARGE_INTEGER;
begin
hTimer := CreateWaitableTimer(nil, True, 'WaitableTimer');
if hTimer = 0 then
Exit;
liDueTime.QuadPart := -10000000 * lNumberOfSeconds;
SetWaitableTimer(hTimer, TLargeInteger(liDueTime), 0, nil, nil, False);
repeat
lBusy := MsgWaitForMultipleObjects(1, hTimer, False,
INFINITE, QS_ALLINPUT);
Application.ProcessMessages;
Until lBusy = WAIT_OBJECT_0;
CloseHandle(hTimer);
End;
begin
while True do
begin
writeln('Output');
wait(10);
end;
end.
?
Leonid Troyanovsky (2008-03-11 23:19:00) [10]
> DVM © (11.03.08 22:22) [18]
> Почему? Смущает цикл сообщений в консольном приложении без
> окон?
Смущает смешение парадигм (или подсистем).
Одна - обработка потоков (streams) символов, а вторая - обработка
неупорядоченного ввода (GUI).
А если делиться на два разнородных потока (threads), то консольное приложение полностью лишится своей (возможной) привлекательности.
В качестве примера можно представить, хотя бы, неуклюжесть
реакции, скажем, на завершение такого приложения или всей сессии.
Для GUI приложения консольные включения (типа AllocConsole) также выглядят некими франкенштейнами, но, при желании, можно сделать
подобные черты и более цивилизованными.
Резюме: или делать в консоли второй поток с Waitable Timer, или делать
обычное GUI приложение (с окном верхнего уровня).
Ну, и возможны некие компромиссы, скажем, поручать периодические
действия Schedule.
--
Regards, LVT.
DVM (2008-03-11 22:22:00) [11]
> Leonid Troyanovsky © (11.03.08 15:53) [17]
Почему? Смущает цикл сообщений в консольном приложении без окон? Так цикл сообщений он не только для окон нужен. А цикл там будет в любом случае, так почему бы не использовать цикл ообщений.
Leonid Troyanovsky (2008-03-11 15:53:00) [12]
> mr. Eof (11.03.08 00:10) [14]
> Работает, спасибо =)
Будет ошибкой проектирования.
--
Regards, LVT.
mr. Eof (2008-03-11 00:20:00) [13]Спасибо, я добавлю
Elec3C (2008-03-11 00:19:00) [14]При завершении программы желательно KillTimer.
mr. Eof (2008-03-11 00:10:00) [15]Работает, спасибо =)
DVM (2008-03-11 00:05:00) [16]
program Project1;
{$APPTYPE CONSOLE}
uses
windows, messages, SysUtils;
procedure TimerProc(wnd: HWND; uMsg:UINT; idEvent: UINT; dwTime: DWORD); stdcall;
begin
windows.Beep(500,50);
end;
var
Mesg : TMsg;
begin
SetTimer(0, 100, 1000, @TimerProc);
While GetMessage(Mesg,0,0,0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end
end.
mr. Eof (2008-03-10 23:57:00) [17]а у тебя нет рабочего примера с SetTimer ??
что то я внятного не нашел..
DVM (2008-03-10 23:56:00) [18]
> В таком случае буду использовать Sleep.
но с таймером оно правильнее :) Sleep - это своего рода костыль.
mr. Eof (2008-03-10 23:55:00) [19]Спасибо. Это интересно.
В таком случае буду использовать Sleep.
DVM (2008-03-10 23:54:00) [20]
> А как ты думаешь, что будет легче??
Это ловля блох. Sleep(10000) ясное дело будет легче легкого (на микроскопическую величину), и займет меньше системных ресурсов, чем установка таймера.