Synchronizing Threads and GUI in Delphi application
16330 단어 application
//
zSB(3,3)
//]]>
See More About
//
zSB(1,2);if(zs<3){gEI('sp2').className=gEI('sb2').className='hide';}
//]]>
Code submitted by Jens Borrisholt
Multi-threading in Delphi lets you create applications that include several simultaneous paths of execution.
A "normal"Delphi application is single-threaded: all (VCL) objects access their properties and execute their methods within this single thread.
Threads and GUI
To speed up data processing in your application you can decide to include one or more "secondary"threads.When several threads are running in the application a question arises: how to update your GUI (user interface) as a result of a thread execution. The question lies in the TThread class Synchronize method.
To update your application's user interface - main thread - from a secondary thread you need to call the Synchronize method - 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.
An example demo uses several buttons with progress bar, each progress bar displaying the current "state"of the thread execution...
Download source code
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) ;
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
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;
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;
end;
end.
Suggested Reading
//
w('
New posts to the Delphi Programming forums:
//]]>
New posts to the
Delphi Programming forums :
Related Articles
//
zSB(3,3)
//]]>
//
if(z336>0){w('
Advertisement
');adunit('','','about.com',ch,gs,300,250,' 1','bb',3);w('Advertisement
');adunit ('','','about.com',ch,gs,336,155,'1','ps',4);w('//]]>
//
if(zSbL<1)zSbL=3;zSB(2);zSbL=0
//]]>
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Pre-Query SamplesValidate the current query criteria or provide additional query criteria programmatically, just before sending the SELEC...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.