在开发两层数据库软件时,因为网络慢,数据库查询时会出现界面假死情况,想把查询放到线程里面,这样就不会有影响界面的问题了,但是查询得到的记录集如何传递给datagrid之类的控件没有好的办法,请支招。线程数据库
解决方案 »
- delphi string多行文本的操作。。。。
- 大侠们,散分,一个超简单的问题!!!
- 关于文件类型关联的问题
- 北大的校园bbs里看到一篇触动很大的文章(转载)
- 求救,我的这个ISAPI Filter怎么弄都不对啊
- InstallShield打包时,凡是中文文件夹和中文文件名都无法打进去,如何解决?
- 我需要delphi的安装程序文件vcl40.bpl,或delphi4的完整安装程序installshield?
- 学习Delphi有没有类似www.codeguru.com(vc++)一样的网站?
- 极弱智的问题,edit怎么才能变黑呢?
- 各位同行,什么时候我才有资格对自己说我已经精通了???(delphi)
- delphi writeln 写入记事表出现漏写
- IDE设置问题
2、使用内存数据集,诸如ClientDataSet,多线程获取数据后追加至ClientDataSet,注意线程互斥保护
1.主程序單元:
unit TestThreadMainForm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB,TQueryThreadUnit, ComCtrls,
DBGridEh, DBGridEhGrouping, GridsEh;type
TForm1 = class(TForm)
ADODataSet1: TADODataSet;
DataSource1: TDataSource;
Button1: TButton;
StatusBar1: TStatusBar;
DBGridEh1: TDBGridEh;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure ThreadTerminate(Sender :TObject);
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
MyQueryThread :TQueryThread;
begin //CoInitialize(nil);
try
MyQueryThread :=TQueryThread.Create(ADODataset1,DataSource1,StatusBar1);
MyQueryThread.OnTerminate := ThreadTerminate;
MyQueryThread.Resume;
StatusBar1.SimpleText := '請等待,正在打開數據表......';
StatusBar1.SimplePanel := True;
finally
//CoUninitialize;
end;
//ADODataSet1.Open;
end;procedure TForm1.ThreadTerminate(Sender:TObject);
begin
ShowMessage('線程終止顯示!');
end;
end.
2.線程查詢單元:
unit TQueryThreadUnit;interfaceuses
Classes,ADODB,DB,ActiveX,ComCtrls;type
TQueryThread = class(TThread)
private
FDataSet :TADODataSet;
FDataSource :TDataSource;
FStatusBar :TStatusBar;
procedure HookUpUI;
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(ADataSet:TADODataSet;ADataSource:TDataSource;AStatusBar:TStatusBar);virtual;
end;implementation{ 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 TQueryThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ TQueryThread }
constructor TQueryThread.Create(ADataSet:TADODataSet;ADataSource:TDataSource;AStatusBar:TStatusBar);
begin
inherited Create(True);
FDataSet := ADataSet;
FDataSource := ADataSource;
FStatusBar := AStatusBar;
FreeOnTerminate := True;
//Resume;
end;procedure TQueryThread.Execute;
begin
{ Place thread code here }
CoInitialize(nil);
try
if not FDataSet.Active then FDataSet.Open;
Synchronize(HookUpUI);
finally
CoUninitialize;
end;
end;procedure TQueryThread.HookUpUI;
begin
FDataSource.DataSet := FDataSet;
FStatusBar.SimpleText := '已經打開數據表!';
end;
end.
一般的做法是通过Provider从数据库读取数据,将结果赋给TClientDataSet.Data,这样,与TClientDataSet连接的感知控件就能显示结果了。
由于通过Provider取数和将结果赋给TClientDataSet完全可以分到不同的线程中处理,所以,实现你的需求没啥问题