我是Windows服务的新手,我需要做这项工作...... 我从here获取了代码,这只是此代码的副本。但我正在尝试从服务中做一些HTTP请求。对于这个工作,我选择创建一个新线程,并在线程中执行请求...这部分代码是(这是我从上面链接上的原始代码中添加的唯一内容):
type
MyThread = class(TThread)
strict private
protected
constructor Create;
procedure Execute; override;
end;
constructor MyThread.Create;
begin
inherited Create(false);
FreeOnTerminate:= true;
Priority:= tpNormal;
end;
procedure MyThread.Execute;
var
IdHTTP: TIdHTTP;
begin
while not(Terminated) do
begin
IdHTTP := TIdHTTP.Create(nil);
IdHTTP.Get('http://google.com');
IdHTTP.Free;
Sleep(5000);
end;
end;
我在 OnServiceCreate 中调用MyThread.Create过程,但它只发出一个请求。它不应该每5秒做一个请求,而线程还活着吗?
答案 0 :(得分:8)
我在OnServiceCreate
中调用了MyThread.Create过程
TService.OnCreate
事件是创建线程的错误位置。该事件不仅在服务启动时触发,而且在(未)安装服务时触发。而是在OnStart
事件中创建线程,仅在服务启动时触发。
它只发出一个请求。它不应该每5秒做一个请求,而线程还活着吗?
您的主题没有进行任何错误处理。如果TIdHTTP.Get()
因任何原因失败,则会引发一个您没有捕获的异常,因此您的线程将自行终止。
在每次循环迭代中也没有理由重新创建TIdHTTP
对象。
我强烈建议你不要使用FreeOnTerminate=true
。保持为假,然后终止并释放OnStop
/ OnShutdown`事件中的主题。
尝试更像这样的事情:
type
MyThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create;
end;
constructor MyThread.Create;
begin
inherited Create(False);
end;
procedure MyThread.Execute;
var
IdHTTP: TIdHTTP;
begin
IdHTTP := TIdHTTP.Create(nil);
try
while not Terminated do
begin
try
IdHTTP.Get('http://google.com');
// success, do something
except
// failed, do something else
end;
Sleep(5000);
end;
finally
IdHTTP.Free;
end;
end;
type
TService1 = class(TService)
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
private
Thread: MyThread;
end;
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
Thread := MyThread.Create;
Started := True;
end;
procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
if Thread <> nil then
begin
Thread.Terminate;
while WaitForSingleObject(Thread.Handle, WaitHint-100) = WAIT_TIMEOUT do
ReportStatus;
FreeAndNil(Thread);
end;
Stopped := True;
end;