• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

SynchronizingThreadsandGUIinDelphiapplication

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Synchronizing Threads and GUI

 
 
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.

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
一个关于DelphiXML处理单元的BUG发布时间:2022-07-18
下一篇:
让UltraEdit-32成为Delphi7编译器的工具设置发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap