网上查了很多资料,看了很多关于线程TThread的使用,并动手操作,但均未能达到想要的效果。我所要的效果是,线程执行耗时的操作而不影响主程序,用户使用没有卡顿的感觉。知道是使用线程编程解决,后来经过不断的摸索,终于达到想要的效果,而代码也只是二十几行,后面直接调用即可。
type
TDBQueryThread = class(TThread)
private
qryTemp: TADOQuery;
sqlstr: string;
public
constructor Create(qry: TADOQuery; StrSql1: string); virtual;
procedure Execute; override; //线程创建后自动执行的代码
end;
constructor TDBQueryThread.Create(qry: TADOQuery; StrSql1: string);
begin
inherited Create(True); // 生成线程对象
qryTemp := qry; //传递数据集参数
sqlstr := StrSql1; //传递SQL查询语句
FreeOnTerminate := True; //完成后释放
Resume; // 启动线程
end;
procedure TDBQueryThread.Execute;
begin
with qryTemp do
begin
Close;
SQL.Text := sqlstr;
Open;
end;
end;
下面是调用线程的代码,创建线程后会自动执行线程的Execute里的代码,只需要一行即可:
TDBQueryThread.Create(qry1, 'select * from dbo.T_User');
效果是线程执行后自动运行,查询数据多的操作没有卡顿的感觉了。代码知道这样用,但还有很多不明白的地方,如线程创建是传递参数,更新的是qryTemp,但实际也更新了qry。本来是形参传递,但在线程是实参传递了
下面再添加一个例子,三个文本分别添加文字,可以三个同进添加,多个线程同时运行,而不影响主程序:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids, StdCtrls, ExtCtrls;
type
TMainForm = class(TForm)
pnlBottom: TPanel;
pnlButtons: TPanel;
btnGo: TButton;
btnExit: TButton;
mmo1: TMemo;
mmo2: TMemo;
btn2: TButton;
btn3: TButton;
btn4: TButton;
mmo3: TMemo;
procedure btnExitClick(Sender: TObject);
procedure btnGoClick(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
procedure btn4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
uses
QryU, DB, DBTables;
type
TMyThread = class(TThread)
protected
mmoth: TMemo;
constructor Create(mmo1: TMemo); virtual;
procedure Execute; override;
end;
constructor TMyThread.Create(mmo1: TMemo);
begin
inherited Create(True);
FreeOnTerminate := True;
mmoth := mmo1;
Resume;
//
end;
procedure TMyThread.Execute();
var
i: Integer;
begin
i := 0;
while i < 5001 do
begin
mmoth.Lines.Add(IntToStr(i));
i := i + 1;
end;
end;
var
MyThread: TMyThread;
procedure TMainForm.btn2Click(Sender: TObject);
var
Isquit: Boolean;
I: Cardinal;
begin
if Assigned(MyThread) and (not MyThread.Finished) then //判断线程是否结束
begin
ShowMessage('no Finished'); //线程正在执行,避免冲突,弹出提示而不同时执行
end
else
begin
MyThread := TMyThread.Create(mmo1);
end;
end;
procedure TMainForm.btn3Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread := TMyThread.Create(mmo2);
end;
procedure TMainForm.btn4Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread := TMyThread.Create(mmo3);
end;
procedure TMainForm.btnExitClick(Sender: TObject);
begin
Close;
end;
procedure TMainForm.btnGoClick(Sender: TObject);
begin
end;
end.