Просто в дополнение к ответу cgatian, для TypeScript 1.x
Если вы все еще видите ошибки, пожалуйста, конкретно укажите index.d.ts в опциях вашего компилятора.
"files": [
"typings/index.d.ts"
]
Это должна быть служба? Не могли бы вы настроить запланированное задание в Windows?
Я бы спал.
Оба варианта не имеют гарантии точного времени, но спящий режим возвращает ресурсы другим процессам.
TTimer не является потокобезопасным. Если вам нужно использовать в потоке подход, подобный TTimer, я бы предложил TDSiTimer из DSiWin32 .
Никогда не используйте TTimer в службе, он не всегда будет вести себя так, как вы ожидаете, и не является потокобезопасным.
В рамках службы я всегда использую собственные переменные временного интервала и сплю между временами выполнения задачи. Чтобы служба оставалась отзывчивой, я сплю на короткие периоды, обычно 1-2000 мс, а затем обрабатываю сообщения, прежде чем проверять свой интервал, чтобы узнать, пора ли выполнять «задачу». Если еще не время, вернитесь в режим сна и проверьте снова после - в цикле. Таким образом, вы возвращаете ресурсы, но также можете реагировать на ввод пользователя (Стоп, Пауза) перед выполнением следующей задачи.
Это не так. действительно имеет значение, что ваша служба является однопоточной, поскольку код службы всегда будет вызываться в разных контекстах потока:
Service Manager будет запускать, останавливать, приостанавливать и возобновлять выполнение службы и запрашивать текущее состояние службы.
Сама служба будет иметь по крайней мере один поток, выполняющий реальную работу, который должен реагировать на запросы от диспетчера службы, изменять состояние выполнения службы по запросу и возвращать запрошенную информацию. Сервис должен реагировать на запросы от Service Manager в разумно короткие сроки, в противном случае он будет считать, что служба зависла, и убьет ее. Вот почему - если служба может иметь долго выполняющийся или блокирующий код - может быть лучше иметь более одного потока службы.
Использовать ли Sleep () или сообщения таймера также зависит от наличие подкачки сообщений в служебных ветках. Если у вас нет насоса сообщений, вы должны использовать Sleep () или обратные вызовы по таймеру. Если у вас все равно есть насос сообщений, потому что вам нужно общаться с другими процессами или потоками через сообщения Windows, или вам нужно делать что-то OLE, то, возможно, проще всего использовать сообщения таймера.
Несколько лет назад я написал служба для синхронизированного фонового выполнения задач, аналогичная функциям Windows at
или Unix cron
. Он не использует большую часть VCL, только некоторые базовые классы.
Я всегда использую что-то вроде этого в Сервисе:
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