Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2009.01.11;
Скачать: [xml.tar.bz2];

Вниз

Проблема с таймером   Найти похожие ветки 

 
mr. Eof   (2008-03-10 23:22) [0]

Здравствуйте.

Подскажите, как можно запускать в программе выполнение функций по истечению определенного врмени?
Тоесть, мне надо выполнять набор неких действий каждые 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% и тд...
Подскаите выход?


 
DVM ©   (2008-03-10 23:25) [1]


> Использовать стандартный компонент таймер я не могу

можешь тот, что устанавливается через API функцию SetTimer. Там есть вариант без окон. Через функцию обратного вызова.


 
Лабух   (2008-03-10 23:25) [2]

Почему нельзя использовать стандартный компонент?


 
DVM ©   (2008-03-10 23:28) [3]


> Данный вариант бесспорно хорош)), однако грузит процессор
> под 100% и тд...

sleep(1000 или даже 5 или 0) вставь в цикл.


 
DVM ©   (2008-03-10 23:29) [4]


> Почему нельзя использовать стандартный компонент?

Потому что очевидно у него консольная программа.


 
mr. Eof   (2008-03-10 23:35) [5]

Да, программа действительно консольная.
Сейчас попробую с SetTimer.
Спасибо всем за ответы!


 
mr. Eof   (2008-03-10 23:41) [6]

А что вообще наиболее эввективно (по отношению к ресурсам ПК) использовать?
SetTimer или sleep??


 
DVM ©   (2008-03-10 23:48) [7]

пока у тебя будет цикл, без sleep (или чего то подобного) тебе все равно не обойтись. Иначе цикл будет крутиться максимально быстро и отожрет все процессорное время.


 
mr. Eof   (2008-03-10 23:51) [8]

Да, я согласен.
А как ты думаешь, что будет легче??
Sleep с бесконечным циклом:
 while True do
   begin
     sleep(10000);
     writeln("Bingo!");
   end;


Или SetTimer (рабочего примера пока нет =) ).


 
DVM ©   (2008-03-10 23:54) [9]


> А как ты думаешь, что будет легче??

Это ловля блох. Sleep(10000) ясное дело будет легче легкого (на микроскопическую величину), и займет меньше системных ресурсов, чем установка таймера.


 
mr. Eof   (2008-03-10 23:55) [10]

Спасибо. Это интересно.
В таком случае буду использовать Sleep.


 
DVM ©   (2008-03-10 23:56) [11]


> В таком случае буду использовать Sleep.

но с таймером оно правильнее :) Sleep - это своего рода костыль.


 
mr. Eof   (2008-03-10 23:57) [12]

а у тебя нет рабочего примера с SetTimer ??
что то я внятного не нашел..


 
DVM ©   (2008-03-11 00:05) [13]


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-11 00:10) [14]

Работает, спасибо =)


 
Elec3C ©   (2008-03-11 00:19) [15]

При завершении программы желательно KillTimer.


 
mr. Eof   (2008-03-11 00:20) [16]

Спасибо, я добавлю


 
Leonid Troyanovsky ©   (2008-03-11 15:53) [17]


> mr. Eof   (11.03.08 00:10) [14]

> Работает, спасибо =)

Будет ошибкой проектирования.

--
Regards, LVT.


 
DVM ©   (2008-03-11 22:22) [18]


> Leonid Troyanovsky ©   (11.03.08 15:53) [17]

Почему? Смущает цикл сообщений в консольном приложении без окон? Так цикл сообщений он не только для окон нужен. А цикл там будет в любом случае, так почему бы не использовать цикл ообщений.


 
Leonid Troyanovsky ©   (2008-03-11 23:19) [19]


> DVM ©   (11.03.08 22:22) [18]

> Почему? Смущает цикл сообщений в консольном приложении без
> окон?

Смущает смешение парадигм (или подсистем).

Одна - обработка потоков (streams) символов, а вторая - обработка
неупорядоченного ввода (GUI).

А если делиться на два разнородных потока (threads), то консольное приложение полностью лишится своей (возможной) привлекательности.
В качестве примера можно представить, хотя бы, неуклюжесть
реакции, скажем, на завершение такого приложения или всей сессии.

Для GUI приложения консольные включения (типа AllocConsole) также выглядят некими франкенштейнами, но, при желании, можно сделать
подобные черты и более цивилизованными.

Резюме: или делать в консоли второй поток с Waitable Timer, или делать
обычное GUI приложение (с окном верхнего уровня).
Ну, и возможны некие компромиссы, скажем, поручать периодические
действия Schedule.

--
Regards, LVT.


 
mr. Eof   (2008-03-11 23:38) [20]


> Резюме: или делать в консоли второй поток с 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.


?


 
DVM ©   (2008-03-11 23:48) [21]


> mr. Eof  

А что в конечном результате ты хочешь сделать? А т не очень понятны все эти пляски с таймерами и задержками.


 
mr. Eof   (2008-03-12 00:17) [22]


> А что в конечном результате ты хочешь сделать? А т не очень
> понятны все эти пляски с таймерами и задержками.

DVM, в данном случае это не принципиально. Руководство поставило задачу модифицировать существующее приложение, и одним из требований является постоянная работа сервиса..
Я сделал это используя sleep и на 1й взгляд все норм работает.
Однако после сообщений Leonid Troyanovsky, я сильно засомневался...


 
Сергей М. ©   (2008-03-12 08:31) [23]


> постоянная работа сервиса


А до постановки задачи она, надо понимать, непостоянная ?
И как же эта "непостоянность" проявляется ?


> lBusy := MsgWaitForMultipleObjects(1, hTimer, False,
> INFINITE, QS_ALLINPUT);
> Application.ProcessMessages;


Какой еще Application ?
У тебя же консольное приложение, судя по приведенному коду, не использует VCL ?..


 
Leonid Troyanovsky ©   (2008-03-12 13:37) [24]


> mr. Eof   (11.03.08 23:38) [20]

> Я правильно понимаю, что имеется ввиду это:

Только не это :)

Или два потока в консоли, или GUI приложение (да хотя бы и сервис)
с окном верхнего уровня.

--
Regards, LVT.


 
DVM ©   (2008-03-12 13:45) [25]


> и одним из требований является постоянная работа сервиса.
> .

Так сервис или консольное приложение? Пока что сервисами в примерах выше и не пахнет.


 
Dm1tr1y   (2008-03-12 19:49) [26]

Сервис. Результат - dll.
В консоли я тестирую, так как похоже.
По поводу Application.ProcessMessages - да, не подойдет. Я не заметил сразу :)


 
Dm1tr1y   (2008-03-12 19:50) [27]

Да, до этого приложение было консольным и запускалось по требованию пользователя, вручную.


 
Германн ©   (2008-03-13 00:57) [28]


> В консоли я тестирую, так как похоже.

А что мешает тестировать в сервисе?

P.S. А вот использовать разные ники в одной ветке некошерно. Можешь огрести за нарушение правил форума.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2009.01.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.005 c
2-1227964423
Евгений
2008-11-29 16:13
2009.01.11
Доступ к таблице Access через ListView


15-1226297587
Slider007
2008-11-10 09:13
2009.01.11
С днем рождения ! 10 ноября 2008 понедельник


2-1228034039
Шурик
2008-11-30 11:33
2009.01.11
Нужно исправить код


2-1227687010
cosinus
2008-11-26 11:10
2009.01.11
Как понять, что тот или иной компонент создан?


1-1205323967
0x01
2008-03-12 15:12
2009.01.11
Проблема при работе с DLL





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский