AaronCatolico1 0 Posted November 2 (edited) 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 November 2 by AaronCatolico1 Share this post Link to post
Mark- 29 Posted November 2 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
Remy Lebeau 1392 Posted November 3 (edited) 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 November 3 by Remy Lebeau Share this post Link to post
Remy Lebeau 1392 Posted November 3 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
JohnLM 14 Posted November 3 (edited) 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 November 3 by JohnLM Share this post Link to post
AaronCatolico1 0 Posted November 4 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