Hello,
I am having difficulty to understand how Delphi thread works; I appreciate all helps I get.
Looks developing window service on Delphi requires thread, I have one posted previously and works,
I have few hundreds rows in a table, looping through each row and creating few objects for each row and free them after process complete.
If you look to the code below, you will see I call Processfile within loop every minute, some rows takes more than a minute to complete.
My question, how thread works in this situation? Is the thread handle each call separately, kind of process and go away after done?
===================================== code below ==================
unit mainsrv;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs, Forms, ABSMain, Data.DB;
type
TRssReceiver = class(TService)
ABSTable1: TABSTable;
ABSDatabase1: TABSDatabase;
procedure ServiceAfterInstall(Sender: TService);
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure ServiceShutdown(Sender: TService);
private
{ Private declarations }
RssReceiverThread: TThread;
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
RssReceiver: TRssReceiver;
SecondThread : TSecondThread;
implementation
uses
Winapi.WinSvc, SyncObjs;
{$R *.dfm}
type
TRssReceiverThread = class(TThread)
private
TermEvent: TEvent;
procedure Getlistoffileandprocess;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create;
destructor Destroy; override;
end;
constructor TRssReceiverThread.Create;
begin
inherited Create(False);
TermEvent := TEvent.Create(nil, True, False, '');
end;
destructor TRssReceiverThread.Destroy;
begin
TermEvent.Free;
inherited;
end;
procedure TRssReceiverThread.Execute;
var
Interval: Integer;
begin
Interval := 60000; // check every minute
while not Terminated do
begin
if TermEvent.WaitFor(Interval) = wrTimeout then
Getlistoffileandprocess;
end;
end;
procedure TRssReceiverThread.Getlistoffileandprocess;
begin
RssReceiver.ABSDatabase1.Connected:=True;
RssReceiver.ABSTable1.Open;
RssReceiver.ABSTable1.First;
while not RssReceiver.ABSTable1.Eof do //over 300 files
begin
Processfile( RssReceiver.FieldByName('filepath').asstring, RssReceiver.FieldByName('filetype').asstring);
RssReceiver.ABSTable1.Next;
end;
end;
procedure TRssReceiverThread.Processfile(filepath, filetype:string);
var
Filelist:TABSTable;
Processlist:TABSTable;
begin
//here I have many steps, something like this
try
Filelist:=TABSTable.create(nil);
Processlist:=TABSTable.create(nil);
// do the work for each path.
Finally
Filelist.free;
Processlist.free;
end;
end;
procedure TRssReceiverThread.TerminatedSet;
begin
TermEvent.SetEvent;
end;
{ Service controller procedures. }
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
RssReceiver.Controller(CtrlCode);
end;
function TRssReceiver.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TRssReceiver.ServiceAfterInstall(Sender: TService);
var
hSCM, hService: SC_HANDLE;
Desc: SERVICE_DESCRIPTION;
begin
hSCM := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
if hSCM <> 0 then
try
hService := OpenService(hSCM, PChar(Self.Name), SERVICE_CHANGE_CONFIG);
if hService <> 0 then
try
Desc.lpDescription := 'The service installed.';
ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, @Desc);
finally
CloseServiceHandle(hService);
end;
finally
CloseServiceHandle(hSCM);
end;
end;
procedure TRssReceiver.ServiceShutdown(Sender: TService);
begin
if RssReceiverThread <> nil then
begin
RssReceiverThread.Terminate;
while WaitForSingleObject(RssReceiverThread.Handle, Self.WaitHint) =
WAIT_TIMEOUT do
ReportStatus;
FreeAndNil(RssReceiverThread);
end;
end;
procedure TRssReceiver.ServiceStart(Sender: TService; var Started: Boolean);
begin
RssReceiverThread := TRssReceiverThread.Create;
Started := True;
end;
procedure TRssReceiver.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
ServiceShutdown(Sender);
Stopped := True;
end;
end.