多线程查询

来源:互联网 发布:百度搜索源码 编辑:程序博客网 时间:2024/04/19 20:42

实现多线程同步查询的基本思想是,为每一个查询组件(如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.

原创粉丝点击