I'm either missing a really obvious mistake in my code or I'm just about to head down a very deep thread rabbit hole...
I'm trying to maintain a heartbeat file via separate thread to my main UI thread (as the application is concerned with folder monitoring, any large file being copied into the monitored folder causes any file operations to slow down which causes the application to go non responding).
The heartbeat file is actually a TIniPropStorage for ease of access to a couple of values I want to store in it (machine name and time stamp).
Anyway, I have the heartbeat thread just about working - the file is created and is 'modified' by my thread.
However, for some reason I am not able to write to the file...
The same code worked in my main thread / main unit, but is not working in my thread code.
unit heartbeat_thread;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, IniPropStorage;
type
{THeartBeatThread}
THeartBeatThread = class(TThread)
heartbeatFile: TIniPropStorage;
private
fStatusText: string;
procedure ShowStatus;
procedure heartbeat();
procedure stopHeartBeat();
protected
procedure Execute; override;
public
procedure stop();
var
heartbeatFileName: AnsiString;
heartbeatPeriod: Integer;
beating: Boolean;
constructor Create(CreateSuspended: boolean);
end;
implementation
{ THeartBeatThread }
uses MainUnit;
constructor THeartBeatThread.Create(CreateSuspended: boolean);
begin
FreeOnTerminate := True;
inherited Create(CreateSuspended);
end;
procedure THeartBeatThread.Execute;
begin
heartbeatFile := TIniPropStorage.Create(nil);
heartbeatFile.IniFileName:=heartbeatFileName;
heartbeatFile.Active:=true;
while (beating) do
begin
heartbeat();
sleep(heartbeatPeriod);
end;
heartbeatFile.Destroy;
end;
procedure THeartBeatThread.ShowStatus;
// this method is only called by Synchronize(@ShowStatus) and therefore
// executed by the main thread
// The main thread can access GUI elements, for example Form1.Caption.
begin
MainForm.addToLog(fStatusText);
end;
procedure THeartBeatThread.heartbeat();
var
myMachineName: AnsiString;
begin
myMachineName:= sysutils.GetEnvironmentVariable('COMPUTERNAME');
// Why is this not writing anyhthing to the file?
with heartbeatFile do
begin
WriteString('machineName',myMachineName);
WriteString('heartbeat',FloatToStr(Now()));
end;
fStatusText:='heart beat';
Synchronize(@ShowStatus);
end;
procedure THeartBeatThread.stop();
begin
beating:=false;
stopHeartBeat();
end;
procedure THeartBeatThread.stopHeartBeat();
var
heartbeatBelongsTo, myMachineName: AnsiString;
begin
heartbeatFile.Active:=false;
heartbeatBelongsTo:= heartbeatFile.ReadString('machineName','noMachineNameFound');
myMachineName:= sysutils.GetEnvironmentVariable('COMPUTERNAME');
fStatusText:='hb file belongs to '+heartbeatBelongsTo+', my machine name = '+myMachineName;
Synchronize(@ShowStatus);
if (heartbeatBelongsTo = myMachineName) then
begin
sysutils.DeleteFile(heartbeatFile.IniFileName);
fStatusText:='deleted heart beat file';
Synchronize(@ShowStatus);
end;
end;
end.
(Note, AddToLog() is a function in my main unit that gives me feedback about what my application is doing via a TMemo.)
Where am I going wrong?
Thanks,
FM