TThread在Classes单元中声明,直接从TObject继承下来的,因为,它不是组件.TThread是个抽象类,所以不能创建TThread的实例,而只能创建其派生类的实例.
利用TThread类来编写多线程应用程序的一般步骤如下:
[步骤一]从TThread类派生出一个新的线程类.
[步骤二]创建线程对象
[步骤三]设置线程对象的属性,比如优先级等.
[步骤四]根据具体情况挂起或唤醒线程.
[步骤五]结束线程.
从TThread类派生出一个新的线程类的过程非常简单:通常菜单"File|New|Other..."打开"New Items"对话框,选中"New"页的"ThreadObject"项,单击"OK"按钮,接着在弹出的"NewThread Object"对话框中输入新的线程类的名称.通常线程类的名称以T开头,以Thread结束,例如"TTestThread".
TThread类还有以下的一些属性、方法和事件:
Priority属性:整型,设置线程的优先级.
Return Value属性:返回值,即当线程结束时返回给其他线程的一个数值.
Suspended属性:判断线程是否被挂起.
ThreadID属性:线程标识号,是整个系统中线程的标识号.
DoTerminate过程:产生一个OnTerminate事件,但是不结束线程的执行.
Resume过程:唤醒一个线程继续执行.
Suspend过程:挂起一个线程.
Synchronize过程:由主VCL线程调用的一个同步过程.
Terminate过程:将Terminated属性设置为True,终止线程的执行.
WairFor方法:等待线程的终止并返回Return Value属性的数值.
举例:
建立TThread类代码
unit Unit2;
interface
uses
Classes;
type
TPainterThread =class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
implementation
uses unit1,graphics;//使用了unit1单元(也就是form单元)使用了graphics单元(图像单元,后面clblue会使用)
procedure TPainterThread.Execute;
var
x,y:integer;
begin
randomize;//初始化随机函数
repeat
x:=random(300);
y:=random(form1.ClientHeight);
with form1.Canvas do
begin
lock;//锁定画布
try
pixels[x,y]:=clblue;
finally
unlock;
end;
end;
until Terminated;
end;
end.
form调用TThread方法举例:
在form上建立两个button组件.
unit Unit1;
interface
uses
Windows, Messages, SysUtils,Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Unit2;//引用线程所在的实例
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
pt:TPainterThread;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
pt:=TPainterThread.Create(false);//开始绘图线程
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
pt.Free;
end;
end.
多线程程序访问VCL的时候要特别注意,只能逐个地实现对VCL的访问.具体可以采用下面的两个方法:
(1) 锁定VCL对象
对于一些具有锁定功能的对象,可以在锁定之后再进去具体操作,比如上面的方法!!!.
(2) 使用Synchronize函数
TThread类的Synchronize过程声明如下:
type TThreadMethod=procedure of object;
procedure Synchronize(Method:TThreadMethod);
其他参数Method为一个不带参数的过程名.在这个不带参数的过程中是一些访问VCL的代码.
对Synchronize的调用是在Execute过程中,用来避免对VCL的并发访问.程序运行期间的具体过程实际上是由Synchronize过程来通知主线程,然后主线程在适当的时机执行Synchronize过程的参数列表中不带参数的过程.在多个线程的情况下,主线程将Synchronize过程所发的通知放到消息队列中,然后逐个地响应这些消息.通过这种机制Synchronize实现了线程之间的同步.
举例:
(一)在窗体上放置一个Imagelist,两个label,一个SpinEdit组件(在"Samples"页),一个Button.为Imagelist装载一系列的动画位图,Button的Caption为"开始".
(二)在单元中的type部分声明一个线程TAnimThread如下:
type
TAnimThread=class(TThread)
private
b:TBitMap;
procedure DrawAnimPic;
protected
procedure Execute; override;
end;
在窗体的Private部分声明一个TAnimThread的实例:
AnimThread:TAnimThread;
并在Var部分定义全局变量
run:Boolean;
(三)在单击按钮时创建TAnimThread的实例,并立即执行该线程.同时处理窗体组件的事件.具体过程参见程度清单如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils,Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin,ImgList;
type
TAnimThread =class(TThread)//声明一个线程
private
b:TBitMap;
procedure DrawAnimPic;
protected
procedure Execute; override;
end;
TAnimWindow = class(TForm)
ImageList1: TImageList;
SpinEdit1: TSpinEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
AnimThread:TAnimThread;//创建一个线程实例
public
{ Public declarations }
end;
var
AnimWindow: TAnimWindow;
run: Boolean;
implementation
{$R *.dfm}
procedure TAnimThread.Execute;
var
x,i:integer;
dir:Boolean;
begin
b:=TBitMap.Create;
b.width:=animwindow.width;
b.height:=32;
b.canvas.pen.color:=clpurple;
b.canvas.brush.color:=clskyblue;
b.canvas.rectangle(0,0,animwindow.width,32);
dir:=false;
x:=0;
i:=0;
repeat
begin
inc(i);
b.canvas.rectangle(0,0,animwindow.width,32);
animwindows.imagelist1.draw(b.canvas,x,0,i);
synchronize(Drawanimpic);
sleep(animwindow.spinedit1.value);
if(x=0) or (x=300) then
dir:=not dir;
if dir then inc(x) else dec(x);
if i>=animwindows.imagelist1.count-1 then
i:=0;
end;
until Terminated;
b.free;
end;
procedure TAnimThread.DrawAnimPic;
begin
//双缓冲技术
Animwindow.Canvas.CopyRect(bounds(0,0,animwindow.Width,32),b.Canvas,bounds(0,0,animwindow.Width,32));
bitblt(animwindow.Canvas.Handle,0,0,animwindow.Width,32,b.Canvas.Handle,0,0,SRCCOPY);
end;
procedure TAnimWindow.Button1Click(Sender: TObject);
begin
run:=not run;
if run then
animthread:=tanimthread.create(false)
else
animthread.free;
if button1.caption='开始'then
button1.caption:='结束'
else
button1.caption:='开始';
end;
procedure TAnimWindow.FormCreate(Sender: TObject);
begin
run:=false;
end;
procedure TAnimWindow.SpinEdit1Change(Sender: TObject);
begin
if spinedit1.value<10 then
begin
button1click(self);
showmessage('延时时间太短!可能影响动画效果!');
end;
end;
procedure TAnimWindow.FormDestroy(Sender: TObject);
begin
if not animthread.terminated then
animthread.free;
end;
end.
DrawAnimPic过程使用了双缓冲技术,即在后台创建一个位图,将所要显示的图片拷贝到该位图上,然后再把该位图拷贝到前右的窗体上,因为该位图不显示,所以窗体不会有闪烁现象.
动画播放经常要用到Sleep函数,其功能就是将当前线程挂起一定的时间间隔.声明如下:
VOID Sleep(
DWORD dwMilliseconds //sleeptime in milliseconds
);
其中dwMilliseconds为间隔时间,单位为毫秒.
多线程的使用(Delphi) delphi多线程实例
更多阅读
痄腮散的使用说明 宝宝炸腮怎么办
腮腺炎,中医学称“痄腮”, 民间也称“猪头肥”。是儿童和青少年中常见的呼吸道传染病,由腮腺炎病毒所引起。冬春季节发病较多,病人是传染源,飞沫的吸入是主要传播途径,接触病人后2-3周发病。腮腺炎主要表现为一侧或两侧耳垂下肿大,肿大的腮
加湿器的使用方法 加湿器正确使用方法
现如今空气质量越来越差,冬季的空气越来越干燥,尤其是北方。再加之冬天使用现如今使用加湿器的用户越来越多,尤其是冬天家里面开了空调,那更是需要空气加湿器了。加湿器的使用方法——【使用方法】◆换水时务必先关掉电源; ◆为确保并延
会员管理软件储值卡 的使用方法 会员储值卡使用说明
会员管理软件(储值卡)的使用方法——简介 日常生活中,我们的商家经常会需要使用会员管理软件,其中一种类型是储值卡会员管理软件。什么是储值卡,很简单,比如去超市买东西办卡,可以预充值,消费的时候从卡里扣除费用。很多行业需要储值卡,如小
批量挂QQ 软件的使用方法 qq邮箱使用方法
批量挂QQ 软件的使用方法——简介 有时候我们有很多个QQ想同时挂机升级,但是可能由于电脑配置太低,或者网速太差而无法实现多个QQ同时挂机,今天给大家介绍一款可以批量挂QQ的软件及其使用方法,希望对有些朋友们有所帮助!批量挂QQ 软件的
电脑与投影仪的使用方法。 实物投影仪使用方法
电脑与投影仪的使用方法。——简介现在电脑的使用已经十分的广泛,我们的生活也因为电脑扩展了很多,在我们的生活里也多了很多其他与电脑连接的辅助工具。下面我来说说投影仪与电脑连接的方法,方便大家经常性的使用,我的方法有什么不对的