-
Здравствуйте. Подскажите, как можно запускать в программе выполнение функций по истечению определенного врмени? Тоесть, мне надо выполнять набор неких действий каждые 10 секунд. !!! Использовать стандартный компонент таймер я не могу !!! Я пытался так: program time;
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% и тд... Подскаите выход?
-
> Использовать стандартный компонент таймер я не могу
можешь тот, что устанавливается через API функцию SetTimer. Там есть вариант без окон. Через функцию обратного вызова.
-
Почему нельзя использовать стандартный компонент?
-
> Данный вариант бесспорно хорош)), однако грузит процессор > под 100% и тд...
sleep(1000 или даже 5 или 0) вставь в цикл.
-
> Почему нельзя использовать стандартный компонент?
Потому что очевидно у него консольная программа.
-
Да, программа действительно консольная. Сейчас попробую с SetTimer. Спасибо всем за ответы!
-
А что вообще наиболее эввективно (по отношению к ресурсам ПК) использовать? SetTimer или sleep??
-
пока у тебя будет цикл, без sleep (или чего то подобного) тебе все равно не обойтись. Иначе цикл будет крутиться максимально быстро и отожрет все процессорное время.
-
Да, я согласен. А как ты думаешь, что будет легче?? Sleep с бесконечным циклом: while True do
begin
sleep(10000);
writeln('Bingo!');
end; Или SetTimer (рабочего примера пока нет =) ).
-
> А как ты думаешь, что будет легче??
Это ловля блох. Sleep(10000) ясное дело будет легче легкого (на микроскопическую величину), и займет меньше системных ресурсов, чем установка таймера.
-
Спасибо. Это интересно. В таком случае буду использовать Sleep.
-
> В таком случае буду использовать Sleep.
но с таймером оно правильнее :) Sleep - это своего рода костыль.
-
а у тебя нет рабочего примера с SetTimer ?? что то я внятного не нашел..
-
program Project1;
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.
-
Работает, спасибо =)
-
При завершении программы желательно KillTimer.
-
Спасибо, я добавлю
-
> mr. Eof (11.03.08 00:10) [14]
> Работает, спасибо =)
Будет ошибкой проектирования.
-- Regards, LVT.
-
> Leonid Troyanovsky © (11.03.08 15:53) [17]
Почему? Смущает цикл сообщений в консольном приложении без окон? Так цикл сообщений он не только для окон нужен. А цикл там будет в любом случае, так почему бы не использовать цикл ообщений.
-
> DVM © (11.03.08 22:22) [18]
> Почему? Смущает цикл сообщений в консольном приложении без > окон?
Смущает смешение парадигм (или подсистем).
Одна - обработка потоков (streams) символов, а вторая - обработка неупорядоченного ввода (GUI).
А если делиться на два разнородных потока (threads), то консольное приложение полностью лишится своей (возможной) привлекательности. В качестве примера можно представить, хотя бы, неуклюжесть реакции, скажем, на завершение такого приложения или всей сессии.
Для GUI приложения консольные включения (типа AllocConsole) также выглядят некими франкенштейнами, но, при желании, можно сделать подобные черты и более цивилизованными.
Резюме: или делать в консоли второй поток с Waitable Timer, или делать обычное GUI приложение (с окном верхнего уровня). Ну, и возможны некие компромиссы, скажем, поручать периодические действия Schedule.
-- Regards, LVT.
-
> Резюме: или делать в консоли второй поток с 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. ?
-
> mr. Eof
А что в конечном результате ты хочешь сделать? А т не очень понятны все эти пляски с таймерами и задержками.
-
> А что в конечном результате ты хочешь сделать? А т не очень > понятны все эти пляски с таймерами и задержками.
DVM, в данном случае это не принципиально. Руководство поставило задачу модифицировать существующее приложение, и одним из требований является постоянная работа сервиса.. Я сделал это используя sleep и на 1й взгляд все норм работает. Однако после сообщений Leonid Troyanovsky, я сильно засомневался...
-
> постоянная работа сервиса
А до постановки задачи она, надо понимать, непостоянная ? И как же эта "непостоянность" проявляется ?
> lBusy := MsgWaitForMultipleObjects(1, hTimer, False, > INFINITE, QS_ALLINPUT); > Application.ProcessMessages;
Какой еще Application ? У тебя же консольное приложение, судя по приведенному коду, не использует VCL ?..
-
> mr. Eof (11.03.08 23:38) [20]
> Я правильно понимаю, что имеется ввиду это:
Только не это :)
Или два потока в консоли, или GUI приложение (да хотя бы и сервис) с окном верхнего уровня.
-- Regards, LVT.
-
> и одним из требований является постоянная работа сервиса. > .
Так сервис или консольное приложение? Пока что сервисами в примерах выше и не пахнет.
-
Сервис. Результат - dll. В консоли я тестирую, так как похоже. По поводу Application.ProcessMessages - да, не подойдет. Я не заметил сразу :)
-
Да, до этого приложение было консольным и запускалось по требованию пользователя, вручную.
-
> В консоли я тестирую, так как похоже.
А что мешает тестировать в сервисе?
P.S. А вот использовать разные ники в одной ветке некошерно. Можешь огрести за нарушение правил форума.
|