Delphi多线程 - 通过线程类TThread新建线程

Delphi中有一个线程类TThread,是用来实现多线程编程的,这里主要举例如何实现及应用,不做深究。以下例程是在Delphi2010环境运行。


一.  建立工程及线程代码框架

1. 新建一个工程。

2. 点击菜单 File -> New -> Other弹出New Items对话框:

3. 选择 Delphi Projects -> Delphi Files ->Thread Object ->OK确定

0036.jpg


4. 在弹出对话框Class Name中输入新建线程的名称,比如TMyThread -> OK确定

0037.jpg


5. Delphi会自动生成部分代码,保存修改文件名后如下:

unit NewThread;
interface
uses
  Classes;
type
  TMyThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;
implementation
{ 
  //这部分注释主要介绍了Synchronize的用法
  //Synchronize的介绍请参考:http://evelee.net/blog/?id=23
  
  Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,
      Synchronize(UpdateCaption);  
  and UpdateCaption could look like,
    procedure TMyThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; 
    
    or 
    
    Synchronize( 
      procedure 
      begin
        Form1.Caption := 'Updated in thread via an anonymous method' 
      end
      )
    );
    
  where an anonymous method is passed.
  
  Similarly, the developer can call the Queue method with similar parameters as 
  above, instead passing another TThread class as the first parameter, putting
  the calling thread in a queue with the other thread.
    
}
{ TMyThread }
procedure TMyThread.Execute;//线程启动后自动执行这里的代码
begin
  { Place thread code here }
end;
end.


二.  编写主线程代码

unit Unit1;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
    Form1: TForm1;
    MyCS:TRTLCriticalSection;//定义临界区全局变量
    
implementation
uses NewThread;//调用线程单元
var
    MyThread:TMyThread;//定义线程
{$R *.dfm}

{启动线程}
procedure TForm1.Button1Click(Sender: TObject);
begin
    MyThread:=TMyThread.Create(false);
end;

{释放线程}
procedure TForm1.Button2Click(Sender: TObject);
begin
      if Assigned(MyThread) and (not MyThread.Finished) then//检查线程是否存在并在运行中
      begin
            MyThread.Terminate;//设置线程结束标志
            MyThread.WaitFor;//等待线程结束
            MyThread.Free;//释放线程
      end;
end;

initialization
    InitializeCriticalSection(MyCS);//初始化临界区全局变量
finalization
    DeleteCriticalSection(MyCS);//结束化临界区全局变量
end.


对于判定线程状态,这里提供一个功能较全面的代码:

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
// return:
//        0-已经释放
//        1-正在运行
//        2-已终止但未释放
//        3-未建立或不存在
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
function TForm3.CheckThread(aThread: TThread): Byte;
var
    i: DWord;
    IsQuit: Boolean;
begin
    if Assigned(aThread) then //存在
    begin
          IsQuit := GetExitCodeThread(aThread.Handle, i);
          if IsQuit then
          begin
                if i = STILL_ACTIVE then
                begin
                    Result := 1
                end
                else
                begin
                    Result := 2;
                end
          end
          else
          begin
                Result := 0; //已经释放
          end;
    end
    else
    begin
          Result := 3; //未建立,或不存在
    end;
end;


三.  编写新线程代码

unit NewThread;

interface
uses
    Classes,Windows;
type
    TMyThread = class(TThread)
    private
      { Private declarations }
    protected
      procedure Execute; override;
    end;
    
implementation
uses Unit1;//调用主线程单元

procedure TMyThread.Execute;
begin
    while not Terminated do
    begin
        EnterCriticalSection(MyCS); //进入临界区
        try
               //这里放置要执行的代码
              Synchronize(
                              procedure
                              begin
                                    //这里放置对VCL界面的更新代码
                              end
                          )
        finally
               LeaveCriticalSection(MyCS); //离开临界区
        end;
        
        sleep(1000);
        if Terminated then//检查线程退出标志
        begin
            break;//Execute执行结束就意味着线程结束
        end;
    end;
end;

end.


标签:Delphi

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://evelee.net/blog/?id=24