实现多线程同步查询的基本思想是,为每一个查询组件(如TQuery组件)创建一个独占的 数据库会话,然后各自进行数据库访问。需要特别注意的是,因为Delphi中的 VCL组件大多都 不是线程安全的,所以应当在线程查询结束后再将DataSource组件与查询组件关联,从而显示 在DBGrid组件中。
下面的例子只实现了静态的线程同步查询,即线程对象是固定的,并随窗体的创建和销毁 而创建和销毁。
下面的例子给出了同时进行的两个线程查询。
线程类:
unit Unit2;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB;
type
TDBThread=class(TThread)
private
{ 线程中的查询组件 }
FQuery: TADOQuery;
{ 与查询组件相关的数据感知组件 }
FDataSource: TDataSource;
{ 连接数据查询组件和数据感知组件的方法 }
procedure ConnectDataSource;
protected
procedure Execute; override;{ 执行线程的方法 }
public
constructor Create(Query: TADOQuery;DataSource: TDataSource;iFlag:Integer); { 线程构造器 }
end;
implementation
{ TDBThread }
procedure TDBThread.ConnectDataSource;
begin
{该方法在查询结束后才调用 }
FDataSource.DataSet := FQuery;
end;
constructor TDBThread.Create(Query: TADOQuery; DataSource: TDataSource;
iFlag: Integer);
begin
FQuery := Query;
FDataSource := DataSource;
FreeOnTerminate := True;
inherited Create(False); //请设为false,否则将不会立即执行
end;
procedure TDBThread.Execute;
begin
try
FQuery.Open; { 打开查询 }
Synchronize(ConnectDataSource);{ 线程同步 }
except
ShowMessage('Query Error'); { 线程异常 }
end;
end;
end.
调用:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, Grids, DBGrids, StdCtrls;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Button1: TButton;
ADOQuery1: TADOQuery;
ADOQuery2: TADOQuery;
DataSource1: TDataSource;
DataSource2: TDataSource;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Q1:TDBThread;
begin
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from tuser');
Q1 := TDBThread.Create(ADOQuery1, DataSource1,1);
// Q1.Destroy;//不可以销毁,否则会出错
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Q1:TDBThread;
begin
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('select * from fplist');
Q1 := TDBThread.Create(ADOQuery2, DataSource2,1);
//Q1.Destroy;//不可以销毁,否则会出错
end;
end.