delphi线程同步_在Delphi应用程序中同步线程和GUI

delphi线程同步

Multi-threading in Delphi lets you create applications that include several simultaneous paths of execution.

Delphi中的多线程使您可以创建包含多个同时执行路径的应用程序。

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.

普通的Delphi应用程序是单线程的,这意味着所有VCL对象都在该单线程中访问其属性并执行其方法。 为了加快应用程序中的数据处理,请包括一个或多个辅助线程。

处理器线程 ( 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.

线程是从应用程序到处理器的通信通道。 单线程程序在执行时需要进行双向通信(往返于处理器)。 多线程应用程序可以打开几个不同的通道,从而加快了执行速度。

线程和GUI ( 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.

当应用程序中正在运行多个线程时,就会出现一个问题,即如何通过执行线程来更新图形用户界面。 答案在于TThread类的Synchronize方法。

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.

要从辅助线程更新应用程序的用户界面或主线程,您需要调用Synchronize方法。 此技术是一种线程安全的方法,可避免访问非线程安全的对象属性或方法或使用非执行主线程中的资源而引起的多线程冲突。

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) ;
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;

Thanks to Jens Borrisholt for submitting this code sample.

翻译自: https://www.thoughtco.com/synchronizing-threads-and-gui-delphi-application-1058159

delphi线程同步

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值