Science, Tech, Math › Computer Science
Synchronizing Threads and GUI in a Delphi
Application
Sample Code for a GUI Delphi Application With Multiple Threads
Share
SHARE Flipboard
FLIP Email
EMAIL
Ad
Synchronizing Threads and GUI.
By Zarko Gajic
Updated January 28, 2019
Multi-threading in Delphi lets you create applications that include several simultaneous
paths of execution.
A normal Delphi application is single-threaded, which means all VCL objects access their
properties and execute their methods within this single thread. To speed up data
processing in your application, include one or more secondary threads.
Processor Threads
A thread is a communication channel from an application to a processor. Single-
threaded programs need communication to flow in both directions (to and from
the processor) as it executes; multi-threaded apps can open several different
channels, thus speeding up execution.
Threads & GUI
When several threads are running in the application, the question arises of how you can
update your graphical user interface as a result of a thread execution. The answer lies in
the TThread class Synchronize method.
Ad
To update your application's user interface, or main thread, from a secondary thread,
you need to call the Synchronize method. This technique is a thread-safe method that
avoids multi-threading conflicts that can arise from accessing object properties or
methods that are not thread-safe, or using resources not in the main thread of execution.
Below is an example demo that uses several buttons with progress bars, each progress
bar displaying the current "state" of the thread execution.
unit MainU;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ExtCtrls;
type
//interceptor class
TButton = class(StdCtrls.TButton)
OwnedThread: TThread;
ProgressBar: TProgressBar;
end;
TMyThread = class(TThread)
private
FCounter: Integer;
FCountTo: Integer;
FProgressBar: TProgressBar;
FOwnerButton: TButton;
procedure DoProgress;
procedure SetCountTo(const Value: Integer) ;
Ad
procedure SetProgressBar(const Value: TProgressBar) ;
procedure SetOwnerButton(const Value: TButton) ;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean) ;
property CountTo: Integer read FCountTo write SetCountTo;
property ProgressBar: TProgressBar read FProgressBar write SetProgressBar;
property OwnerButton: TButton read FOwnerButton write SetOwnerButton;
end;
TMainForm = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
Button2: TButton;
ProgressBar2: TProgressBar;
Button3: TButton;
ProgressBar3: TProgressBar;
Button4: TButton;
ProgressBar4: TProgressBar;
Button5: TButton;
ProgressBar5: TProgressBar;
procedure Button1Click(Sender: TObject) ;
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
{ TMyThread }
constructor TMyThread.Create(CreateSuspended: Boolean) ;
begin
inherited;
FCounter := 0;
FCountTo := MAXINT;
end;
procedure TMyThread.DoProgress;
var
PctDone: Extended;
begin Ad
PctDone := (FCounter / FCountTo) ;
FProgressBar.Position := Round(FProgressBar.Step * PctDone) ;
FOwnerButton.Caption := FormatFloat('0.00 %', PctDone * 100) ;
end;
procedure TMyThread.Execute;
const
Interval = 1000000;
begin
FreeOnTerminate := True;
FProgressBar.Max := FCountTo div Interval;
FProgressBar.Step := FProgressBar.Max;
while FCounter < FCountTo do
begin
if FCounter mod Interval = 0 then Synchronize(DoProgress) ;
Inc(FCounter) ;
end;
FOwnerButton.Caption := 'Start';
FOwnerButton.OwnedThread := nil;
FProgressBar.Position := FProgressBar.Max;
end;
procedure TMyThread.SetCountTo(const Value: Integer) ;
begin
FCountTo := Value;
end;
procedure TMyThread.SetOwnerButton(const Value: TButton) ;
begin
FOwnerButton := Value;
end;
procedure TMyThread.SetProgressBar(const Value: TProgressBar) ;
begin
FProgressBar := Value;
end;
procedure TMainForm.Button1Click(Sender: TObject) ;
var
aButton: TButton;
aThread: TMyThread;
aProgressBar: TProgressBar; Ad
begin
aButton := TButton(Sender) ;
if not Assigned(aButton.OwnedThread) then
begin
aThread := TMyThread.Create(True) ;
aButton.OwnedThread := aThread;
aProgressBar := TProgressBar(FindComponent(StringReplace(aButton.Name, 'Button',
'ProgressBar', []))) ;
aThread.ProgressBar := aProgressBar;
aThread.OwnerButton := aButton;
aThread.Resume;
aButton.Caption := 'Pause';
end
else
begin
if aButton.OwnedThread.Suspended then
aButton.OwnedThread.Resume
else
aButton.OwnedThread.Suspend;
aButton.Caption := 'Run';
end;
Ad
Thanks to Jens Borrisholt for submitting this code sample.
Cite this Article
Delphi Tutorials
Delphi Thread Pool Example Using
AsyncCalls
Database Applications
Multithreaded Delphi Database
Queries
Ad
Application.ProcessMessages Test Dynamic Extended TMenuItem in
PopUp Menu
Delphi Tutorials
Delphi Tutorials Add Items to a TPopUp Delphi Menu
The Dark Side of
Application.ProcessMessages in
Delphi Applications
Hispanic man at desk using laptop
Close up of a programmer working on a
laptop with a monitor mounted behind.
Delphi Tutorials
Using a Function or a Procedure as a
Parameter in Another Function
Delphi Tutorials
How to Display Menu Item Hints in
Ad
Delphi Applications
Delphi Tutorials Businesswoman using laptop in of ce
Edit and Display Boolean Fields using
a CheckBox in Delphi's DBGrid
A woman working at a computer using
software to analyze qualitative data.
Delphi Tutorials
Write Network-Aware Applications
With Delphi
Delphi Tutorials man at computer
Handling Errors and Exceptions in
Delphi Applications
Database Applications
SQL in Delphi
Delphi Tutorials
How to Implement the OnCreate
Event for a Delphi TFrame Object Ad
Two male of ce workers typing on
laptops in of ce
Database Applications
How to Build Console Applications
With No GUI
Learn Something New Every Day
Discover surprising insights and little-known facts about politics, literature, science, and the
marvels of the natural world.
ONE-TAP SIGN UP
Follow Us
TRUSTe
Science, Tech, Math Humanities
Languages Resources
About Us Advertise
Ad
Privacy Policy Cookie Policy
Careers Editorial Guidelines
Contact Terms of Use
California Privacy Notice
ThoughtCo is part of the Dotdash publishing family.
Ad