Служба Windows: Действительно работайте в требуемое время (Delphi)

Просто в дополнение к ответу cgatian, для TypeScript 1.x

Если вы все еще видите ошибки, пожалуйста, конкретно укажите index.d.ts в опциях вашего компилятора.

"files": [
    "typings/index.d.ts"
]
6
задан Jim McKeeth 2 July 2009 в 16:37
поделиться

6 ответов

Это должна быть служба? Не могли бы вы настроить запланированное задание в Windows?

10
ответ дан 8 December 2019 в 02:53
поделиться

Я бы спал.

Оба варианта не имеют гарантии точного времени, но спящий режим возвращает ресурсы другим процессам.

3
ответ дан 8 December 2019 в 02:53
поделиться

TTimer не является потокобезопасным. Если вам нужно использовать в потоке подход, подобный TTimer, я бы предложил TDSiTimer из DSiWin32 .

3
ответ дан 8 December 2019 в 02:53
поделиться

Никогда не используйте TTimer в службе, он не всегда будет вести себя так, как вы ожидаете, и не является потокобезопасным.

В рамках службы я всегда использую собственные переменные временного интервала и сплю между временами выполнения задачи. Чтобы служба оставалась отзывчивой, я сплю на короткие периоды, обычно 1-2000 мс, а затем обрабатываю сообщения, прежде чем проверять свой интервал, чтобы узнать, пора ли выполнять «задачу». Если еще не время, вернитесь в режим сна и проверьте снова после - в цикле. Таким образом, вы возвращаете ресурсы, но также можете реагировать на ввод пользователя (Стоп, Пауза) перед выполнением следующей задачи.

2
ответ дан 8 December 2019 в 02:53
поделиться

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

  • Service Manager будет запускать, останавливать, приостанавливать и возобновлять выполнение службы и запрашивать текущее состояние службы.

  • Сама служба будет иметь по крайней мере один поток, выполняющий реальную работу, который должен реагировать на запросы от диспетчера службы, изменять состояние выполнения службы по запросу и возвращать запрошенную информацию. Сервис должен реагировать на запросы от Service Manager в разумно короткие сроки, в противном случае он будет считать, что служба зависла, и убьет ее. Вот почему - если служба может иметь долго выполняющийся или блокирующий код - может быть лучше иметь более одного потока службы.

Использовать ли Sleep () или сообщения таймера также зависит от наличие подкачки сообщений в служебных ветках. Если у вас нет насоса сообщений, вы должны использовать Sleep () или обратные вызовы по таймеру. Если у вас все равно есть насос сообщений, потому что вам нужно общаться с другими процессами или потоками через сообщения Windows, или вам нужно делать что-то OLE, то, возможно, проще всего использовать сообщения таймера.

Несколько лет назад я написал служба для синхронизированного фонового выполнения задач, аналогичная функциям Windows at или Unix cron . Он не использует большую часть VCL, только некоторые базовые классы.

14
ответ дан 8 December 2019 в 02:53
поделиться

Я всегда использую что-то вроде этого в Сервисе:

unit uCopy;

interface

uses
    Windows, Messages,.......;

procedure MyTimerProc(hWindow : HWND; uMsg : cardinal; idEvent : cardinal; dwTime : DWORD); stdcall;

type
  TFileCopy= class(TService)
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
  private
    { Private declarations }
  public
      { Public declarations }
  end;

VAR 
    timerID :  UINT;

const
 SECONDS = 900000;

procedure TFileCopy.ServiceStart(Sender: TService;
  var Started: Boolean);
Begin
timerID := 0; //Probably not needed.
timerID := SetTimer(0, 1, SECONDS, @MyTimerProc); 
End;

procedure MyTimerProc(hWindow : HWND; uMsg : cardinal; idEvent : cardinal;dwTime : DWORD); stdcall;
Begin
  //Kill timer while trying.. If this function takes longer than the interval to run, I didn't want a build up.  If that was possible.
  KillTimer(0, timerID);
  timerID := 0; //Is it needed?
//DO WORK.
{
//I was Connecting to a Network Drive, Minutes, seconds.....
//I only wanted to run this Every day at 2 AM.
//So I had my timer set to 15 minutes, once it got between 30 and 10 minutes of my 2 AM deadline,
//i killed the existing timer and started a new one at 60000.
//If it was within 10 minutes of my 2 AM, my interval changed to 500.  
//This seems to work for me, my files get copied everyday at 2 AM.
}
//Work Complete.  Start timer back up.
  timerID := SetTimer(0, 1, SECONDS, @MyTimerProc);
End;

procedure TFileCopy.ServiceStop(Sender: TService;
  var Stopped: Boolean);
Begin  
if timerID > 0 then
   KillTimer(0, timerID);
End;

Конечно, в большинстве мест у меня был метод Try..Catch наряду с записью в журналы и отправкой по электронной почте .... У меня уже больше года работает служба, использующая эти методы. Ни в коем случае это не правило. Скажите, пожалуйста, есть ли способ лучше. Я всегда ищу способы улучшить свои знания Delphi. Также извините, если я пропустил крайний срок для публикации в вопросе.

-Trey Aughenbaugh

0
ответ дан 8 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: