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

Вниз

Хочу повесить программу,   Найти похожие ветки 

 
ocean   (2009-10-15 12:08) [0]

Следящую за наступлением события. Событие может происходить раз в неск.часов. Собираюсь поместить на форму TTimer, тикающий раз в 10 мин. Но хотелось бы загрузить системные ресурсы по минимуму. Как это лучше сделать?


 
DVM ©   (2009-10-15 12:09) [1]


> Но хотелось бы загрузить системные ресурсы по минимуму.
> Как это лучше сделать?

А таймер сильно грузит?


 
TUser ©   (2009-10-15 12:10) [2]

Для многих событий есть специальные средства такого рода, например, для изменений в файловой системе, - в ВинАпи.


 
DVM ©   (2009-10-15 12:12) [3]


> ocean   (15.10.09 12:08)  

У стандартного таймера есть только один существенный недостаток. Он может и не тикнуть вовремя.


 
DesWind   (2009-10-15 12:16) [4]

CreateWaitableTimer


 
Anatoly Podgoretsky ©   (2009-10-15 12:25) [5]

> ocean  (15.10.2009 12:08:00)  [0]

Так никакой нагрузки и не будет, также можешь использовать Sleep


 
Дмитрий С ©   (2009-10-15 12:58) [6]

Поток + sleep.


 
Игорь Шевченко ©   (2009-10-15 13:06) [7]

В свое время понадобилась запускалка программ каждые N минут(секунд, часов). У стандартного планировщика минимальный интервал, как я выяснил, не меньше суток (может, ошибся, буду рад на пинок в нужном направлении, чтобы убить изобретенный велосипед)

Написал тупо на таймере

unit main;

interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, HsObjectList, StdCtrls;

type
 TCronCommand = class
 private
   FCommandText: string;
   FInterval: TDateTime;
   FRemaining: TDateTime;
 public
   property CommandText: string read FCommandText write FCommandText;
   property Interval: TDateTime read FInterval write FInterval;
   property Remaining: TDateTime read FRemaining write FRemaining;
 end;

 TCronCommands = class(THsObjectList)
 private
   function GetItems(I: Integer): TCronCommand;
 public
   property Items[I: Integer]: TCronCommand read GetItems; default;
 end;

 TfMain = class(TForm)
   Timer1: TTimer;
   Log: TMemo;
   procedure Timer1Timer(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   FCommandList: TCronCommands;
   procedure ParseCommands;
   procedure ProcessCommand (const Command: string);
 end;

var
 fMain: TfMain;

implementation
uses
 DateUtils;

var
 TimerTick: TDateTime;

{$R *.dfm}

procedure TfMain.FormCreate(Sender: TObject);
begin
 FCommandList := TCronCommands.Create;
 Timer1.Enabled := false;
 ParseCommands;
 Timer1.Enabled := true;
 Log.Lines.Add("Scheduler started");
end;

procedure TfMain.FormDestroy(Sender: TObject);
begin
 FCommandList.Free;
end;

procedure TfMain.ParseCommands;
var
 Worker, Parts: TStringList;
 S: string;
 HH, MM, SS: Integer;
 Interval: TDateTime;
 Item: TCronCommand;
begin
 //Формат записи: every$$hh:mm:ss$$command-text
 Worker := TStringList.Create;
 Parts := TStringList.Create;
 try
   Worker.LoadFromFile(".\Schedule");
   for S in Worker do
     if Copy(S, 1, 1) <> "#" then
     begin
       Log.Lines.Add(Format("processing entry %s", [S]));
       StrBreakApart(S, "$$", Parts);
       if (Parts.Count <> 3) or (not SameText(Parts[0], "EVERY")) then
         raise Exception.CreateFmt("illegal string %s", [S]);
       HH := StrToInt(Copy(Parts[1], 1, 2));
       MM := StrToInt(Copy(Parts[1], 4, 2));
       SS := StrToInt(Copy(Parts[1], 7, 2));
       Interval := EncodeTime(HH, MM, SS, 0);
       Item := TCronCommand.Create;
       Item.Interval := Interval;
       Item.Remaining := Interval;
       Item.CommandText := Parts[2];
       FCommandList.Add(Item);
     end;
 finally
   Worker.Free;
   Parts.Free;
 end;
end;

procedure TfMain.ProcessCommand(const Command: string);
var
 si: TSTARTUPINFO;
 pi: TPROCESSINFORMATION;
 rc: Boolean;
begin
 Log.Lines.Add(Format("Executing: %s", [Command]));
 FillChar(si, SizeOf(si), 0);
 FillChar(pi, SizeOf(pi), 0);
 si.cb := SizeOf(si);
 si.dwFlags := STARTF_USESHOWWINDOW;
 si.wShowWindow := SW_HIDE;
 rc := CreateProcess(nil, PChar(Command), nil, nil, true,
   CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, si, pi);
 Win32Check(rc);
 CloseHandle(pi.hProcess);
 CloseHandle(PI.hThread);
end;

procedure TfMain.Timer1Timer(Sender: TObject);
var
 I: Integer;
begin
 for I := 0 to FCommandList.Count - 1 do
 begin
   FCommandList[I].Remaining := FCommandList[I].Remaining - TimerTick;
   if FCommandList[I].Remaining <= 0 then
   begin
     FCommandList[I].Remaining := FCommandList[I].Interval;
     ProcessCommand(FCommandList[I].CommandText);
   end;
 end;
end;

{ TCronCommands }

function TCronCommands.GetItems(I: Integer): TCronCommand;
begin
 Result := TCronCommand(inherited Items[I]);
end;

initialization
 TimerTick := EncodeTime(0, 0, 1, 0);
end.

Таймер срабатывает раз в секунду.

Точности таймера оказалось достаточно, по моей задаче было безразлично, запустится ли программа раз в 10 минут или раз в 10 минут 10 секунд.


 
Anatoly Podgoretsky ©   (2009-10-15 13:12) [8]

> Дмитрий С  (15.10.2009 12:58:06)  [6]

Если поток, то зачем SLEEP


 
Anatoly Podgoretsky ©   (2009-10-15 13:19) [9]


> В свое время понадобилась запускалка программ каждые N минут(секунд,
>  часов). У стандартного планировщика минимальный интервал,
>  как я выяснил, не меньше суток (может, ошибся, буду рад
> на пинок в нужном направлении, чтобы убить изобретенный
> велосипед)

Интервал 1 день, но этот бы планировщик ничего бы стоил в этом случае, на самом деле он гораздо мощнее, можно в настройках задания указать как интервал повтора (для ежедневно) в 1 минуту минимум и интервал действия от и до, и многое другое. Так что можешь колеса меня на круглые.


 
Дмитрий С ©   (2009-10-15 13:20) [10]


> У стандартного планировщика минимальный интервал, как я
> выяснил, не меньше суток

Есть повтор, можно каждые 5 минут запускать.


 
Skyle ©   (2009-10-15 13:20) [11]


> Игорь Шевченко ©   (15.10.09 13:06) [7]
> В свое время понадобилась запускалка программ каждые N минут(секунд,
>  часов). У стандартного планировщика минимальный интервал,
>  как я выяснил, не меньше суток (может, ошибся, буду рад
> на пинок в нужном направлении, чтобы убить изобретенный
> велосипед)

Это как это?

Добавить задание->Выполнять задание ежедневно->Время начала 00:00, ежедневно. Перед нажатием "Готово" ставим галочку "Установить дополнительные параметры....".

Далее закладка "Расписание". Назначить "ежедневно", жмём "Дополнительно".
Ставим галочку "повторять задание" и задаём периодичность, с которой оно будет выполняться каждый день.

Другая проблема в том, что мы отказались от штатного планировщика в районе IE5.5, потому что он иногда зависал. В какой-то момент надоело и написали свой. Как это сейчас, особенно в свете Шедулер2 из висты, я не знаю.


 
Игорь Шевченко ©   (2009-10-15 13:32) [12]

Anatoly Podgoretsky ©   (15.10.09 13:19) [9]
Дмитрий С ©   (15.10.09 13:20) [10]
Skyle ©   (15.10.09 13:20) [11]

Если не затруднит, как это в синтаксисе команды at выглядит ? (раз в 10 минут выполнить foo.exe)


 
Skyle ©   (2009-10-15 14:13) [13]


> Игорь Шевченко ©   (15.10.09 13:32) [12]
> Если не затруднит, как это в синтаксисе команды at выглядит
> ?

Ну это проблемы at, а не шедулера, другой момент.
at это вообще ущербный обрубок.
В принципе может можно поколдовать с еженедельным запуском заданий + soon.exe. Но проще наверное взять Vista/2008 и воспользоваться ITaskService.


 
Игорь Шевченко ©   (2009-10-15 14:18) [14]

Skyle ©   (15.10.09 14:13) [13]


> Ну это проблемы at, а не шедулера, другой момент.
> at это вообще ущербный обрубок.


Я располагаю только синтаксисом команды at. Если я буду вынужден передавать описание колдовства с назначенными заданиями в деревню Гадюкино Усть-Константинопольского уезда с неизвестной операционной системой там, мне проще написать программу (тем более, написание заняло полчаса)


> + soon.exe.


Что за зверь ?


> Но проще наверное взять Vista/2008 и воспользоваться ITaskService.


Есть Windows 98 и Windows NT4 (минимально сопровождаемые системы)


 
Skyle ©   (2009-10-15 14:21) [15]


> > + soon.exe.
> Что за зверь ?

Из W2k Resource Kit мелкая утилитка. Позволяет запускать задания, созданные с помощью at ..... /k через указанное количество секунд.

Но это велосипед получится, притом очень хреновый.


> > Но проще наверное взять Vista/2008 и воспользоваться ITaskService.
> Есть Windows 98 и Windows NT4 (минимально сопровождаемые
> системы)

Я отталкиваюсь вот от этой статьи
http://msdn.microsoft.com/ru-ru/magazine/cc163350.aspx


 
DVM ©   (2009-10-15 14:34) [16]

На королевстве Делфи есть статья "Таймер, который не подведет" как раз там создается планировщик со строкой конфигурирования в формате CRON


 
DVM ©   (2009-10-15 14:35) [17]

вот
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=434


 
Игорь Шевченко ©   (2009-10-15 14:44) [18]

Skyle ©   (15.10.09 14:21) [15]
DVM ©   (15.10.09 14:34) [16]

Первое, что я сделал, когда мне надо было решить задачу - изучил синтаксис команды at. Не нашел нужной мне возможности запускать каждые 10 минут (причем 10 минут - это не абсолютная точность, просто "примерно каждые 10 минут").
Второе, что я сделал - начал искать бесплатные порты Cron под Windows. Не нашел или то, что нашел, не смог запустить.
Третье - за полчаса написал свою программу и доволен.


 
Empleado ©   (2009-10-15 14:53) [19]

Я извиняюсь, я не сильно специалист, а зачем там таймер-то? (Наверняка я что-то не понял)

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


 
Игорь Шевченко ©   (2009-10-15 14:56) [20]


> Событие наступило: SetEvent


А кто его установит ?


 
clickmaker ©   (2009-10-15 15:02) [21]

> В отдельном потоке безустанно ждем это событие

чем это отличается от Sleep?


 
Empleado ©   (2009-10-15 15:03) [22]


> А кто его установит ?

Тогда надо уточнять о каком событии идет речь.
В своем коде (т.е. есть ли возможность его менять), или же это событие типа "жена хлопнула дверью".


 
Anatoly Podgoretsky ©   (2009-10-15 15:12) [23]

> Игорь Шевченко  (15.10.2009 14:18:14)  [14]

В синтаксисе at нет таких возможносте.
Но у тебя очень жесткие ограничения по ОС, поэтому легче будет написать программу.
Можно было воспользоваться scheduller API, но в 98 нет служб, да и не уверен, что вообще есть АТ


 
Anatoly Podgoretsky ©   (2009-10-15 15:25) [24]

> clickmaker  (15.10.2009 15:02:21)  [21]

Разница есть, пока ждем с помощью sleep то все в потоке заблокировано.
А так или выходим или по событию (сигнализируем) или по таймауту.


 
clickmaker ©   (2009-10-15 15:33) [25]

> пока ждем с помощью sleep то все в потоке заблокировано

а при "безустанно ждем это событие" разве нет?


 
Anatoly Podgoretsky ©   (2009-10-15 15:48) [26]

> clickmaker  (15.10.2009 15:33:25)  [25]

Конечно нет, ожидаем события в другом потоке и от туда сигналим, а в основном потоке ждем например по WaitForSingleObject С ТАЙМАУТОМ


 
clickmaker ©   (2009-10-15 16:10) [27]

> Конечно нет, ожидаем события в другом потоке и от туда сигналим,
> а в основном потоке ждем

ну так а чем это отличается от
repeat
  Sleep(ScheduleInterval);
  DoTask();
until Terminated;

?


 
KilkennyCat ©   (2009-10-15 16:23) [28]

взять настольную лампу, прикрепить к абажуру электромагнит. пока есть ток, элмаг удерживат стальной шарик. пропал ток - шарик падает, подскакивает от стола и прилетает на клавишу "Ентер".
Момент наступления исследуемого события можно отследить несколькими способами, например, приклеенным к монитору фотодатчиком или матрицей от фотоаппарата, которые отловят визуально. Если виуально событие не проявляет себя, можно ловить излучение от процессора и смотреть там. Нашей программе осталось среагировать на нажатие клавиши. Код - минимальный.


 
Anatoly Podgoretsky ©   (2009-10-15 16:23) [29]

> clickmaker  (15.10.2009 16:10:27)  [27]

Хорошо давай практически, представь себе следующую задачу.
Есть UDP клиент, которые посылает сообщение и ожидает ответа в течение 30 секунд максимум. Если запустить SLEEP(30000) то ответ придет только черз 30 секунд, тоже с самое с WaitForSingleObject.

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

Как можешь предложить другое решение?


 
Anatoly Podgoretsky ©   (2009-10-15 16:24) [30]

> clickmaker  (15.10.2009 16:10:27)  [27]

Нужен метод SleepAndWakeup


 
clickmaker ©   (2009-10-15 16:50) [31]

> [29] Anatoly Podgoretsky ©   (15.10.09 16:23)

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


 
Anatoly Podgoretsky ©   (2009-10-15 16:58) [32]

> clickmaker  (15.10.2009 16:50:31)  [31]

Ну вот опять мы про разные вещи. Но ты согласен с моим решением для данного случая.


 
qwer_qwer   (2009-10-15 19:47) [33]

Есть ещё портированный cron для Windows.



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

Форум: "Прочее";
Текущий архив: 2009.12.13;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.007 c
15-1255503976
Человек_ищущий_фильтр
2009-10-14 11:06
2009.12.13
Контент-фильтры


2-1256647118
И. Павел
2009-10-27 15:38
2009.12.13
Определения щелчка на Серых полях в StringGrid


15-1255375330
Petr V. Abramov
2009-10-12 23:22
2009.12.13
как бороться с IE8


2-1256669978
Евгений Р.
2009-10-27 21:59
2009.12.13
Имитация WEB сервера


2-1256117947
xyz
2009-10-21 13:39
2009.12.13
перебор выделенных строк в DBGridEh





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский