Delphi把多线程相关的API封装在TThread这个类中,可以方便实现多线程运用。按住Ctrl就可以看到TThread类源码。由于TThread是一个抽象类,所以不能直接创建实例,要创建其派生类的实例。
一般的使用流程是这样的:
1、先新建一个以TThread为父类的派生类;
2、覆盖构造函数,将特定的参数传递进来,保存为类的私有变量;
3、覆盖Execute方法,将线程要实现的操作放到这个过程中;
4、如果需要与主线程VCL同步的话,调用Synchronize方法;
5、Execute执行完后线程自行终止,如果指定了终止事件则执行OnTerminate指定的过程。
为啥要使用线程,先看一个例子。
file-new-application,创建一个应用程序,点击button按钮在放置在窗体上.onclick事件代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
i:real;
begin
i:=1;
repeat
i:=i+1/i
until i>9000000;
end;
运行后,点击button按钮后,不能用鼠标移动窗体,点击运行-程序复位才能恢复正常。
使用线程来做
file-new-other-ThreadObject建立unit2,输入名称test,重写Execute方法
procedure ThreadTest.Execute;
var
i:real;
begin
i:=1;
repeat
i:=i+1/i
until i>9000000;
end;
在form1所在单元uses unit2,在添加一个button事件如下
procedure TForm1.Button7Click(Sender: TObject);
begin
ThreadTest.Create(false); //false表示线程创建后立即执行.
end;
运行程序,点击button2,可以移动窗体.这就是使用线程的好处,可以同步运行。
线程的相关操作,线程的启动暂停恢复终止以及设置优先级
新建一个应用程序,在窗体上放置2个Edit控件,5个button控件,再按上述方法建立一个线程度单元test.
test代码如下:
unit test;
interface
uses
Classes,Windows,Controls, Forms,Stdctrls,SysUtils;
type
test = class(TThread)
private
AEdit:TEdit; //三个私有变量
MaxLoop:Integer;
CurrentLoop:Integer;
protected
procedure Execute; override; //重写Execute方法
procedure DisLoop; //自定义过程显示循环次数
public
constructor Create(Edit:TEdit;Max:integer); //重写构造函数
end;
implementation
{ test }
constructor test.Create(Edit: TEdit; Max: integer);
begin
inherited Create(False);
AEdit:=Edit;
MaxLoop:=Max;
FreeOnTerminate:=True;
end;
procedure test.DisLoop;
begin
AEdit.text:=IntToStr(CurrentLoop);
end;
procedure test.Execute;
var
I:Integer;
begin
for I:=0 to MaxLoop do
begin
CurrentLoop:=I;
Synchronize(DisLoop); //调用DisLoop过程
if Terminated then Exit; //判断Terminated属性,看线程是否终止
end;
end;
end.
窗体单元代码如下:
private
{ Private declarations }
procedure ThreadDone(Sender:TObject); //定义私有过程
public
{ Public declarations }
end;
var
Form1: TForm1;
ThreadsRunning:Integer; //定义线程数变量
MyThread1,MyThread2:test; //两个线程对象
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject); //启动线程
begin
ThreadsRunning:=2;
MyThread1:=test.Create(Edit1,50000);
MyThread1.OnTerminate:=ThreadDone;
MyThread2:=test.Create(Edit2,50000);
MyThread2.OnTerminate:=ThreadDone;
Button2.Enabled:=False;
end;
procedure TForm1.ThreadDone(Sender: TObject);
begin
dec(ThreadsRunning); //线程数自减
if ThreadsRunning=0 then
Button2.Enabled:=True;
end;
procedure TForm1.Button3Click(Sender: TObject); //线程暂停
begin
MyThread1.Suspended:=True;
end;
procedure TForm1.Button4Click(Sender: TObject); //恢复线程
begin
MyThread1.Suspended:=False;
end;
procedure TForm1.Button5Click(Sender: TObject); //线程终止
begin
MyThread1.Terminate;
end;
procedure TForm1.Button6Click(Sender: TObject); //设置线程优先级
begin
MyThread2.Priority:=tpHighest;
end;
end.