Home > Enterprise >  Reading thread's fields from synchronized event handler
Reading thread's fields from synchronized event handler

Time:09-28

Is it safe to read a thread object's fields from an event handler called by the Synchronize procedure?

For example:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;

type
  TMyThread = class(TThread)
  public
    Max : Integer;
    Position : Integer;
    OnPositionChanged : TNotifyEvent;
    procedure Execute(); override;
  end;

  TForm1 = class(TForm)
    ProgressBar1: TProgressBar;
    procedure FormCreate(Sender: TObject);
  private
    procedure MyOnPositionChanged(Sender : TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  Th : TMyThread;

procedure TMyThread.Execute();
begin
  while not Terminated do
  begin
    //doing stuffs
    Sleep(500);

    //position   1
    Inc(Position);

    //event handler
    if(Assigned(OnPositionChanged)) then
    begin
      Synchronize(
        procedure()
        begin
          OnPositionChanged(Self);
        end
      );
    end;

    //check for reaching the max value
    if(Position = Max)
    then Terminate;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //preparing thread
  Th := TMyThread.Create(True);
  Th.FreeOnTerminate := True;
  Th.Max := ProgressBar1.Max;
  Th.Position := ProgressBar1.Position;
  Th.OnPositionChanged := MyOnPositionChanged;

  //starting thread
  Th.Start;
end;

procedure TForm1.MyOnPositionChanged(Sender : TObject);
begin
  //updating progressbar
  ProgressBar1.Position := (Sender as TMyThread).Position;
end;

end.

I'm wondering if there could be some thread-safety problem in reading the thread's fields from the main thread while the other thread is running

CodePudding user response:

Yes, this is generally safe. The thread's Execute() method is blocked while Synchronize() is running, so the thread won't be updating the fields while the main thread is using them.

Where this can break down is if you happen to have another thread updating the same fields without Synchronize()'ing access to them.

  • Related