Jump to content
AaronCatolico1

Multi-Threading Example Code

Recommended Posts

I'm new to using Delphi with RAD Studio. I would like someone to show me a basic example of how to use a thread. I've been looking for examples online for a very basic example and haven't found anything good.

I want to have a simple Label1 and a Button1 on a form. When I click the button, I'd like to see Label1 increment up by 500 milliseconds on it's own thread.

Can someone show me a very basic example. I'd greatly appreciate it.

 

Here's what I've tried, but keep getting the error message: "E2036: variable needed" right next to the Synchronize($UpdateUI)

 

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, System.SyncObjs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    Counter: Integer;
  public
    { Public declarations }
  end;



{ TMyThread is the class that will handle our background work }
MyThread = class(TThread)
private

  x: Integer;
  msg: string;
protected
  procedure Execute; override;
  procedure UpdateUI;
public
  constructor Create;
end;



var
  Form1: TForm1;



implementation

{$R *.fmx}



{Create the TThread}
constructor MyThread.Create;
begin
  inherited Create(False); // False means it will start right away
  FreeOnTerminate := True; // Free memory when finished
end;



{Worker Thread}
procedure MyThread.Execute;
   var i:integer;
begin
  // Simulate some work by looping and sleeping
  for i := 1 to 1000 do
  begin
    Sleep(10); // Simulate work (1 second per iteration)
    msg := '# ' + IntToStr(i);
    Synchronize(@UpdateUI); // Update UI safely from the main thread
  end;
  msg := 'FINISHED!';
  showmessage('FINISHED!!!');
  Synchronize(@UpdateUI);
end;



{Update the UI}
procedure MyThread.UpdateUI;

begin
     Form1.Label1.Text := inttostr(x);

end;



procedure TForm1.Button1Click(Sender: TObject);

begin
     MyThread.Create; // Create and start the thread
end;

end.

 

Edited by AaronCatolico1

Share this post


Link to post

Which version of Delphi are you using?

10.2, "Synchronize" is protected.

 

I have always used Queue to access the main thread.

 

Queue(procedure begin <some procedure>; end);

 

But, I do not use FMX.

 

 

Share this post


Link to post
17 hours ago, Mark- said:

Which version of Delphi are you using?

10.2, "Synchronize" is protected.

The non-static Synchronize() method has always been protected.  That is perfectly fine when calling it from within the thread's Execute() or DoTerminate() methods.  There are also static Synchronize() methods available which are public and can be called outside of a TThread object.

Quote

But, I do not use FMX.

This is not a VCL vs FMX issue, since TThread is common to both of them.

Edited by Remy Lebeau

Share this post


Link to post
19 hours ago, AaronCatolico1 said:

I'm new to using Delphi with RAD Studio. I would like someone to show me a basic example of how to use a thread. I've been looking for examples online for a very basic example and haven't found anything good.

Did you read the documentation yet? Writing Multithreaded Applications

19 hours ago, AaronCatolico1 said:

Here's what I've tried, but keep getting the error message: "E2036: variable needed" right next to the Synchronize($UpdateUI)


Synchronize(@UpdateUI); // Update UI safely from the main thread

 

Simply get rid of the @ symbol, pass the method by name only.

Synchronize(UpdateUI); // Update UI safely from the main thread

 

Share this post


Link to post

I am not a Thread guru, though I do browse around as it is something I want to learn eventually. 

 

So I tried the code snippet in XE7, but didn't work at first, then took out the "@"  (before reading Remy's reply) and although the routine appeared to work, the Label did not get updated.  And after looking through the code, I saw that var x was never called/assigned.  Then I added x=i and it worked!  The Lable now gets updated in real-time, even while dragging the form around the screen during the thread's operation. 

 

  // Simulate some work by looping and sleeping
  for i := 1 to 1000 do
  begin
    Sleep(10); // Simulate work (1 second per iteration)
    msg := '# ' + IntToStr(i); x:=i;
    Synchronize(UpdateUI); // Update UI safely from the main thread
  end;

PS:  I made a VCL project. 

 

Edited by JohnLM

Share this post


Link to post
On 11/3/2024 at 11:35 AM, Remy Lebeau said:

Did you read the documentation yet? Writing Multithreaded Applications

Simply get rid of the @ symbol, pass the method by name only.


Synchronize(UpdateUI); // Update UI safely from the main thread

 

Thank you! I discovered this to be the case the other day.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×