Windows服务和TThread

时间:2015-07-08 17:46:09

标签: delphi

我是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秒做一个请求,而线程还活着吗?

1 个答案:

答案 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;