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.