【问题标题】:thread in service application under delphi xe does not workdelphi xe下服务应用程序中的线程不起作用
【发布时间】:2012-09-10 04:44:59
【问题描述】:

'MyThread' 没有运行。我不知道问题是否发生在“DataTransferServiceStart”程序上。我猜“DataTransferServiceStart”程序没有执行。 IDE是德尔福XE。请帮帮我,非常感谢。

线程的单位:

unit Unit_MyThread;

interface

uses
  Classes, SysUtils;

type
  TMyThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation


procedure TMyThread.Execute;
var
  log: TextFile;
  logPath: String;
  i: Integer;
begin
  logPath := 'd:\test.log';
  AssignFile(log, logPath);
  Append(log);
  i := 0;
  while not self.Terminated do
  begin
    Sleep(1);
    Writeln(log, IntToStr(i));
    if i=10 then
      Terminate;
    i := i + 1;
  end;
  CloseFile(log);
end;

end.

主要服务单位:

unit Unit_main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
  ExtCtrls, DB, ADODB, Unit_MyThread;

type
  TDataTransferService = class(TService)
  DBSrc: TADOConnection;

  procedure DataTransferServiceStart(Sender: TService; var Started: Boolean);
  procedure DataTransferServiceContinue(Sender: TService; var Continued: Boolean);
  procedure DataTransferServicePause(Sender: TService; var Paused: Boolean);
  procedure DataTransferServiceStop(Sender: TService; var Stopped: Boolean);

  public
    function GetServiceController: TServiceController; override;
  end;
var
  DataTransferService: TDataTransferService;
  MyThread: TMyThread;
implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  DataTransferService.Controller(CtrlCode);
end;

function TDataTransferService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TDataTransferService.DataTransferServiceStart(Sender: TService;
  var Started: Boolean);
begin
  MyThread := TMyThread.Create(False);
  Started := True;
end;

procedure TDataTransferService.DataTransferServiceContinue(Sender: TService;
  var Continued: Boolean);
begin
  MyThread.Start;
  Continued := True;
end;

procedure TDataTransferService.DataTransferServicePause(Sender: TService;
  var Paused: Boolean);
begin
  MyThread.Suspended := true;
  Paused := True;
end;

procedure TDataTransferService.DataTransferServiceStop(Sender: TService;
  var Stopped: Boolean);
begin
  MyThread.Terminate;
  Stopped := True;
end;

end.

【问题讨论】:

  • 哪里失败了。它是如何失败的。
  • 'd:\test.log' 是否已经存在?
  • “不起作用”是什么意思具体?如果您需要帮助,您需要提供我们可以用来尝试提供给您的信息。如果不解释你的意思,“不起作用”是没有意义的。
  • 请尝试以具体和信息丰富的方式提出您的问题。例如,好的指导方针是 catb.org/esr/faqs/smart-questions.html 奖励:当你遵循这样的指导方针时,你会让自己变得更好地发现问题,有时自己找到解决方案,“黄鸭”原则。
  • @David 该线程看起来没有运行。我没有发现问题。

标签: multithreading delphi service adoconnection


【解决方案1】:

您的服务很可能无法启动,因为您将TADOConnection 组件放入您的服务中。您不能在服务中执行此操作。由于 ADO 是 COM,因此您必须使用 CoInitialize(nil)CoUninitialize 初始化每个线程,并且只能在其中创建/使用您的数据库组件。

uses
  ActiveX;

procedure TDataTransferService.DataTransferServiceStart(Sender: TService;
  var Started: Boolean);
begin
  CoInitialize(nil);
  DBSrc:= TADOConnection.Create(nil);
  //Initialize and Connect DBSrc
  MyThread := TMyThread.Create(False);
  Started := True;
end;

procedure TDataTransferService.DataTransferServiceStop(Sender: TService;
  var Stopped: Boolean);
begin
  MyThread.Terminate;
  //Disconnect DBSrc
  DBSrc.Free;
  CoUninitialize;
  Stopped := True;
end;

在这里阅读:Ok to use TADOConnection in threads

【讨论】:

  • 您的代码中有一个额外的CoUnitialize。您在DataTransferServiceStart 中调用了一次CoInitialize,但在DataTransferServiceStopExecute 中的finally 块中调用了CoUnitialize
  • 哎呀,我的意思是删除第一个块。当我发布它时,我很着急。
  • 嗯.. 我注意到“DBSrc: TADOConnection”,但忽略了它,因为它似乎没有在任何地方创建。
  • 好吧,如果它在 private 部分之前(在这种情况下甚至没有私有部分),这意味着它直接嵌入到服务中,这意味着它是在应用程序运行时自动创建的初始化
  • @ReiYau,最好的办法是将所有代码封装在线程中,包括数据库。你仍然需要担心CoInitialize(nil),因为它在一个线程中;只是不要把它放在你的服务的主线程中。这在技术上是可行的,但始终不鼓励将代码直接放入服务中——通常的做法是将所有代码包含在一个线程中,并在服务启动时运行该线程。
猜你喜欢
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
相关资源
最近更新 更多