CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

在C/S结构中如何使用两种以上的线程模型?具体如何调用?

楼主dana(dana)2001-07-28 18:00:17 在 Delphi / VCL组件开发及应用 提问

问题点数: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

相关问题

  • 在C#中如何实现调用带参数的线程
  • 线程调用execute
  • C调用C#?
  • C#中多个线程要同时调用form上的窗体控件,如何使这些线程同步。
  • 多线程调用组件
  • 线程调用问题
  • 线程之间的调用
  • 线程中调用参数
  • 调用线程的错误~
  • c++调用perl

关键词

  • 线程
  • 代码
  • 数据库
  • 查询
  • 执行
  • 数据
  • fdatabase
  • fquery
  • tquerythread
  • fsession

得分解答快速导航

  • 帖主:dana
  • DepYuka
  • DepYuka

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo