2014-08-27 2 views
0

Это мои требования:
Нужна работа или задание, которое работает 24/7 с настраиваемым интервалом времени (в Delphi).Необходима помощь в планировании службы

Что я сделал до сих пор:
Так что я решил пойти на службу Windows. Затем я создал службу Windows в Delphi.

Процесс
1. Дата создания службы Windows Start():

procedure TDemo.ServiceStart(Sender: TService; var Started: Boolean); 
begin 
    MyServiceThread := TMyThread.Create(False); //Call the thread 
    MyServiceThread.Resume; 
end; 

2. служба остановки для Windows(); Выполнить метод

procedure TDemo.ServiceStop(Sender: TService; var Stopped: Boolean); 
begin 
    MyServiceThread.Terminate; 
end; 
  1. нити:

    procedure TMyThread.Execute; begin MyTask(); end;

MyTask() имеют некоторые функциональные возможности и может занять от 30 секунд до 5 раз мин чтобы выполнить поставленную задачу.

Если теперь я запустил Сервис, он вызывает метод execute и вызовет MyTask() внутри него. Тогда i t завершает задачу. Это произойдет только один раз. Потому что нет петли вообще.

Затем я создал планировщик задач и установить временной интервал 10 минут и вызовите пакетный файл, который начинается моя служба Windows, и Остановки.

Теперь все работает нормально. Каждые 10 минут мои задачи были завершены.

Какая еще возможность сделать это вместо планировщика заданий? Можно ли делать внутри самого Сервиса? какой из них лучший?

мышление и нашли один решения:
1.Creating таймер внутри Thread. Но таймеру нужно установить время как настраиваемое. Может быть один день или одна неделя и т. Д.

Какова максимальная поддержка времени таймером?

Можно ли использовать таймер?

Есть ли другой способ сделать это?

Пожалуйста, дайте мне некоторое предложение, чтобы найти лучшее решение.

+1

Почему бы не использовать планировщик системы? Зачем изобретать колесо? –

ответ

0

Прежде всего, я не знаю вашу версию Delphi, но, как правило, TThread.Resume устарел. Вы должны использовать TThread.Start. Но даже при этом вам не нужно запускать поток, потому что он создается с параметром False - т.е. не приостановлено.

Execute() выполняет только один раз, потому что вы сделали это так.

Код, приведенный ниже, представляет собой простую нить, которая «выполняет» в течение временного интервала.

TMyThread = class(TThread) 
    private  
     fRefreshInterval: Integer; // milliseconds 
     fTerminateEvent: TEvent; 

     procedure SetRI(const Value: Integer); 
    protected 
     procedure Execute; override;  
    public 
     constructor Create(const aRefreshInterval: Integer = 600000); 
     destructor Destroy; override; 
     property RefreshInterval: Integer write SetRI; 
    end; 

//// implementation 

constructor TMyThread.Create; 
begin 
    inherited Create(False); 
    fRefreshInterval := aRefreshInterval; 
    fTerminateEvent := TEvent.Create(nil, True, False, ''); 
    Priority := tpLowest; 
    FreeOnTerminate := True; 
end; 

destructor TMyThread.Destroy; 
begin 
    try 
    if not Terminated then 
    begin 
     Terminate; 
     fTerminateEvent.SetEvent;  
    end; 

    fTerminateEvent.Free; 
    except 
    // 
    end; 
    inherited; 
end; 

procedure TMyThread.Execute; 
begin 
    while not Terminated do 
    begin 
    try 

     // your code here 

    except 
     // something bad happened 
    end; 

    fTerminateEvent.WaitFor(fRefreshInterval); 
    end; 
end; 

procedure TMyThread.SetRI(const Value: Integer); 
begin 
    InterlockedExchange(fRefreshInterval, Value); 
end; 

Если вы хотите, чтобы выполнить свою задачу каждые XX минут, вы должны иметь в виду, время, необходимое для выполнения задачи и должны сделать что-то вроде:

procedure TMyThread.Execute; 
var 
    taskStartedAt: Cardinal; 
    taskDuration: Cardinal; 
begin 
    while not Terminated do 
    begin 
    taskStartedAt := GetTickCount; 
    try 

     // your code here 

    except 
     // something bad happened 
    end; 

    taskDuration := GetTickCount - taskStartedAt; 

    if (fRefreshInterval > taskDuration) then 
     fTerminateEvent.WaitFor(fRefreshInterval - taskDuration); 
    end; 
end; 

Во всяком случае, TTimer и Task Scheduler тоже варианты.

+0

Спасибо, за ваш быстрый ответ. Можно ли настроить интервал таймера один? Могу ли я использовать ini-файл для настройки временного интервала таймера? –

+0

Вы можете настроить временной интервал через свой 'Свойство RefreshInterval' по своему усмотрению. Кроме того, вы можете установить его изначально через входной параметр конструктора. –

0

Наличие таймера внутри службы Windows является одним из вариантов. Вы также можете проверить, завершил ли ваш предыдущий экземпляр, прежде чем начинать новый. Однако, если вам нужно время от времени контролировать службы, это может оказаться неправильным вариантом.

В течение многих лет я обнаружил, что Autosys является самым полезным планирующим агентом.Он поставляется с клиент-серверной моделью. Таким образом, вы можете управлять заданиями с помощью своего клиентского инструмента Autosys.

TechScheduler - еще один вариант, но теперь он очень старомодный.

1

Вы можете использовать подход создания таймера.

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

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

Теперь, если использование систем closk не является вариантом из-за того, что пользователь может изменить его, используйте свой собственный счетчик, который будет увеличен каждый раз, когда срабатывает таймер. Поэтому теперь вам нужно только адаптировать логику синхронизации к вашей счетной системе.

EDIT: Подход, который я предлагаю, используется во время многопользовательских игр, где каждая задача занимает определенное время. Таким образом, сервер просто хранит, когда определенное событие будет происходить на основе того, когда команда для какой-либо задачи была проигнорирована, и сколько времени требуется для завершения этой задачи.

0

Я предпочел бы использовать подход «Запланированная задача». Это обычный подход Windows на такой задаче, и вам потребуется только создать консольное приложение, которое называется , каждый интервал, который вы определяете в запланированной задаче.