在C/S结构中如何使用两种以上的线程模型?具体如何调用?
问题点数:100、回复次数:7Top
1 楼DepYuka()回复于 2001-07-28 18:25:18 得分 50
以下是我经常用到的SQL多线程查询的Thread代码。关键就是每一个查询用的Query控件都要受到TSession的管理,而且Query用Open或者Execute方法的时候,一定要在另一个线程里。
使用这个Thread,你先create,然后把想执行的SQL语句赋值给TQueryThread.SQLText,再把显示用的DBGrid赋值给TQueryThread.DBGrid.然后用TQueryThread.Resume就可以运行了,详细的自己看看代码吧。还有其它用法的。
unit TQueryThread_Unit;
interface
uses
Classes,dbtables,db,Dialogs,Sysutils,DBGrids;
type
TSQLModelType = (stSelect,stExecute,stProcSelect);
TQueryThread = class(TThread)
private
{ Private declarations }
FQuery : TQuery;
FSession : TSession;
FDataBase : TDataBase;
FDataSource : TDataSource;
WarningMessage :String;
procedure SetDBGrid;
procedure ShowWarning;
protected
procedure Execute; override;
public
SQLText : String;
SQLModel : TSQLModelType ;
DBGrid : TDBGrid;
constructor Create(AOwner:TComponent);
destructor Destroy;override;
end;
implementation
constructor TQueryThread.Create(AOwner:TComponent);
begin
{一个Database只能让一个线程执行查询,所以要自己Create一个Session,
一个DataBase,一个Query,和一个DataSource,DataSource也是须的,
要不然在DBGrid指针的移动时候会等待直到SQL查询完毕。
如果有DataSource就不用等。线程会慢慢把数据放入DataSource,
然后在DBGrid上显示出来。}
FSession := TSession.Create(AOwner) ;
FSession.AutoSessionName := true ;
FSession.KeepConnections := true ;
FSession.Open;
FDataBase := TDatabase.Create(AOwner) ;
FDataBase.SessionName := FSession.SessionName ;
FDataBase.DatabaseName := 'DB_'+FSession.SessionName ;
FDataBase.DriverName := 'MSSQL' ; {使用MS SQL Server作为后台数据库}
FDataBase.LoginPrompt := False ;
FDataBase.Params.Add('DATABASE NAME=test') ;{使用 SQL Server上的Test库}
FDataBase.Params.Add('USER NAME=sa') ;
FDataBase.Params.Add('PASSWORD=') ;
FDataBase.Params.Add('SERVER NAME=dep') ;{这里请改为自己的服务器名字}
FQuery := TQuery.Create(AOwner) ;
FQuery.SessionName := FSession.SessionName ;
FQuery.DatabaseName := FDataBase.DatabaseName ;
FDataSource := TDataSource.Create( AOwner );
FDataSource.DataSet := FQuery ;
FreeOnTerminate := False ;
WarningMessage := '' ;
SQLModel := stSelect ;
inherited Create( True );
end;
destructor TQueryThread.Destroy;
begin
FSession.Close;
//一定要先CloseFSession,然后才Free,要不然会等待直到SQL查询完毕。
FSession.Free;
FQuery.Free;
FDataBase.Free;
FDataSource.Free;
end;
procedure TQueryThread.SetDBGrid;
Begin
DBGrid.DataSource := FDataSource ;
end;
procedure TQueryThread.ShowWarning;
Begin
MessageDlg( WarningMessage , mtWarning , [mbOK] ,0 );
end;
procedure TQueryThread.Execute;
Var
i : integer;
begin
try
if SQLText = '' then
begin
WarningMessage := '没有指定SQL查询语句.';
Synchronize( ShowWarning );
end
else if (DBGrid = nil) then
begin
WarningMessage := '没有指定DBGrid.';
Synchronize( ShowWarning );
end
else
begin
FQuery.Close;
FQuery.SQL.Text := SQLText ;
case SQLModel of
stSelect ,stProcSelect:
Begin
FQuery.Open;
Synchronize( SetDBGrid );
End;
stExecute: Begin
FQuery.ExecSQL;
End;
end;
end;
except
on E:EDBEngineError do
Begin
WarningMessage := '数据库运行出错。' + #13 + '错误代码:' ;
for i:= 0 to E.ErrorCount -1 do
WarningMessage := WarningMessage + #13+ IntToStr( E.Errors[i].ErrorCode ) +': ' + E.Errors[i].Message;
Synchronize( ShowWarning );
End
else
raise;
end;
end;
end.
Top
2 楼dana(dana)回复于 2001-07-28 18:36:29 得分 0
为什么你不需要进行线程转换,
比如在增加数据时是使用single 退出时也要执行离开DCOM的线程,以及进入另一个新的线程模式aparment,什么你的代码不需要呢?Top
3 楼DepYuka()回复于 2001-07-28 19:00:47 得分 50
这里并没有涉及到两个线程之间的通讯或者同步的事情,也不存在要锁定数据库的情况,当然不用这些代码啦。我用的是MS SQL Server,如无特定情况,这些都可以不考虑,如果用paradox之类的数据库,就要考虑这些问题啦。
还有,我用的是BDE访问数据库,不涉及DCOM的问题啊。
你说是线程转换是什么意思?怎么我从来没见过这个名词?是我见识太少?其实我不是高手,我只是想帮帮人而已。
是了,以上的TQueryThread,退出线程要先,suspend,然后才Free,这样的话可以在SQL查询正在执行的时候中断查询,我试过的,查1M条记录出来,还没有查完,也可以退出,跟踪了代码的执行情况和内存情况,没有问题。Top
4 楼dana(dana)回复于 2001-07-28 19:56:30 得分 0
具体我也不太清楚,我在李维的系统篇中看到DCOM可以使用多种线程模式。Top
5 楼halfdream(哈欠)回复于 2001-07-29 01:46:36 得分 0
我也不知道线程转换。。。
等我仔细看看:)
Top
6 楼hellojw(呵呵,是我吗)回复于 2001-07-30 11:34:36 得分 0
对:DepYuka() 和dana(dana):
可以和我联系吗?我有很多这方面的问题向你们请教,这段时间我都烦死了。
我的 OICQ:31374226
email:ganzhipeng@21cn.com
能留下你们的联系方式吗?
谢谢!!!Top
7 楼halfdream(哈欠)回复于 2001-08-01 21:39:29 得分 0
DepYuka() ,
程序没有用到COM, 同线程模型无关。
有点不明白的是,
为什么不直接创建包含TDataBase等组件的数据模块,而单独分别创建各个组件呢?
那样不是既省事又不易错吗?
就连BORLAND自己有一些代码都是这样做的。
Top




