Recent

Author Topic: [SOLVED] Can't write to TIniPropStorage programatically from thread  (Read 140 times)

fatmonk

  • Full Member
  • ***
  • Posts: 199
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.

Code: [Select]
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
« Last Edit: September 17, 2019, 05:38:04 pm by fatmonk »

fatmonk

  • Full Member
  • ***
  • Posts: 199
Re: Can't write to TIniPropStorage from thread
« Reply #1 on: September 17, 2019, 01:36:37 pm »
OK, I think I got it.. I hadn't set the iniSection so it didn;t have anywhere to store the values.

Setting that sorted it.

(I was originally doing this via an object added to the main UI form and that makes it obvious what you need to set up initially.

-FM
« Last Edit: September 17, 2019, 05:37:35 pm by fatmonk »