CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

▁▂▃▄▅▆▇ 线程中使用TClientDataSet的可能性有吗???▇▆▅▄▃▂▁

楼主Crob(Take Everything Easy!)2001-11-02 20:25:53 在 Delphi / VCL组件开发及应用 提问

TClientDataSet通过Midas连接远端数据模块,由于数据处理量大,我考虑将一部分数据处理工作另外开一个线程,这样就不会影响到主线程的工作了.  
   
  我自己做了TThread继承的线程类,在类中定义TClientDataSet.  
  线程如果单独执行会报出类"XXXX不是一个数组的错误".   但我如果我在主线程中执行TThread.Execute完全可以运行  
   
      TChkThread   =   class(TThread)  
          m_bChkId:   boolean;  
          mDays:   integer;    
          mhandle:   integer;  
          sConn:   TSocketConnection;  
          cds_tmp   :   TClientDataSet;  
          //cds_tmp会在Create中初始化并连接成功  
          constructor   Create(days:   integer;   bId:   boolean);  
          procedure   Execute;   override;  
          destructor   Destroy;   override;  
          procedure   chkcustid();     //我的处理函数,在Execute中执行  
          procedure   chkmDays(days:   integer);  
      end;  
   
  这可能是VCL的缺陷,但我还是想知道可不可以在线程中使用TClientDataSet.  
   
  300分,如果解决再给300!!!!!  
  问题点数:300、回复次数:18Top

1 楼Crob(Take Everything Easy!)回复于 2001-11-02 20:42:02 得分 0

upupTop

2 楼cobi(我是小新)回复于 2001-11-02 20:50:47 得分 0

XXXX指的是什么?  
  我想线程中是应该可以用clientdataset的,而且你现在的问题也不一顶是它的原因Top

3 楼Crob(Take Everything Easy!)回复于 2001-11-02 21:07:09 得分 0

XXXX   =   Variant,具体错误没记下来  
   
  肯定是线程的问题,你不用怀疑了.  
  我在主线程中调用Execute是可以正常执行的.  
   
  有些控件是不支持线程安全的,   我只是想知道有没有可能在线程中使用TClientDataSet.Top

4 楼Crob(Take Everything Easy!)回复于 2001-11-02 21:11:34 得分 0

具体错误是  
   
  Project   xxx.exe   raised   exception   class   EAccessViolation   with   message'   Access   violation   at   address   .................Write   of   address   0000030.   Process   stoped   Use   step   or   .....  
   
  很常见的错误提示,另外我连接的是SQL   server   2000Top

5 楼xzm2000(傻B)回复于 2001-11-02 21:26:41 得分 0

看看tclientdataset的fetchondemand是否为trueTop

6 楼Miracle(新一代的开山怪)回复于 2001-11-02 21:47:19 得分 0

应该可以把,我还没试过,估计可能需要调用CoInitialize()Top

7 楼Miracle(新一代的开山怪)回复于 2001-11-02 21:57:48 得分 300

我写了如下代码进行测试,没有发生任何问题。  
  unit   Unit2;  
   
  interface  
   
  uses  
      Classes,   DBClient;  
   
  type  
      TrdABC   =   class(TThread)  
      private  
          {   Private   declarations   }  
          fCDS:TClientDataset;  
      protected  
          procedure   Execute;   override;  
      end;  
   
  implementation  
  uses  
      ActiveX,   DB;  
  {   Important:   Methods   and   properties   of   objects   in   VCL   or   CLX   can   only   be   used  
      in   a   method   called   using   Synchronize,   for   example,  
   
              Synchronize(UpdateCaption);  
   
      and   UpdateCaption   could   look   like,  
   
          procedure   TrdABC.UpdateCaption;  
          begin  
              Form1.Caption   :=   'Updated   in   a   thread';  
          end;   }  
   
  {   TrdABC   }  
   
   
  procedure   TrdABC.Execute;  
  begin  
      FreeOnTerminate:=true;  
      CoInitialize(nil);  
      try  
          fCDS:=TClientDataset.Create(nil);  
          try  
              with   FCDS.FieldDefs.AddFieldDef   do  
              begin  
                  DataType:=ftInteger;  
                  Name:='ID';  
              end;  
              fCDS.CreateDataSet;  
              {   Place   thread   code   here   }  
          finally  
              fCDS.Free;  
          end;  
      finally  
          CoUnInitialize;  
      end;  
  end;  
   
  end.  
  Top

8 楼Crob(Take Everything Easy!)回复于 2001-11-03 10:00:30 得分 0

我试试  
   
  如果成功决不失言Top

9 楼Crob(Take Everything Easy!)回复于 2001-11-03 11:14:01 得分 0

to   Miracle()  
   
  看了你的例子,   发现对我没什么用,   因为你只是在线程中建立了本地的数据集  
  而我是要从无端数据源取数据集,不用CoInitialize也可以,ClientDataSet并没用到Ole接口   ,   我想不用初始化的.  
   
  我的程序中也可以线程中操作本地数据集,   但不能在线程中发送CommandText到服务器.  
   
  我要求的是  
  procedure   TrdABC.Execute;  
  begin  
      FreeOnTerminate:=true;  
      fCDS:=TClientDataset.Create(nil);  
          try  
              with   FCDS   do  
              begin  
                  Close();  
                  CommandText   :=   'SELECT   *   FROM   .....';  
                  Open();   //线程中执行这里会出错  
              end;  
          finally  
              fCDS.Free;  
          end;Top

10 楼Crob(Take Everything Easy!)回复于 2001-11-03 17:05:08 得分 0

faint~~~~~~~~~~~~~Top

11 楼Miracle(新一代的开山怪)回复于 2001-11-03 17:16:34 得分 0

呵呵,我一般不这样用。因为多数Delphi所创建的MIDAS服务器都是STA(Single-Threaded   Apartment)的,每个Apartment只能有一个线程进入,而且中途不允许换人,你这样在多线程中呼唤STA服务器当然无法正确执行。除非你做到在同一个线程中初始化服务器连接-转换服务器接口等一些列操作,或者自己手工编写线程间的转换(Marshaling)代码,又或者把服务器写成MTA,否则注定无法成功的。Top

12 楼Miracle(新一代的开山怪)回复于 2001-11-03 17:18:34 得分 0

还有,你上面的例子,好像没有设置RemoteServer和Provider,是为了示意而省略了?  
      FreeOnTerminate:=true;  
      fCDS:=TClientDataset.Create(nil);  
          try  
              with   FCDS   do  
              begin  
                  Close();  
                  CommandText   :=   'SELECT   *   FROM   .....';  
                  Open();   //线程中执行这里会出错  
              end;  
          finally  
              fCDS.Free;  
          end;   Top

13 楼Miracle(新一代的开山怪)回复于 2001-11-03 17:20:41 得分 0

又及,使用ClientDataset会调用Midas.dll中的服务,也就是说使用了COM,所以在独立线程中处理ClientDataset时,最好使用CoInitialize。Top

14 楼Crob(Take Everything Easy!)回复于 2001-11-03 17:32:12 得分 0

我是省略了  
   
  我还试过将SocketConnection也封装在线程类中,   但还是一样.  
  看来是没办法了  
   
  我会给分的Top

15 楼Miracle(新一代的开山怪)回复于 2001-11-03 17:36:09 得分 0

呵呵,因为以前很少来CSDN,我现在一共才171分,如果你给我300,我可真是发了……Top

16 楼Crob(Take Everything Easy!)回复于 2001-11-03 17:45:44 得分 0

我分多得很  
  难得问一次问题的  
   
  马上给分  
   
  我的QQ:2850178Top

17 楼halfdream(哈欠)回复于 2001-12-02 19:26:11 得分 0

 
  TO   :CROB    
  >>'''ClientDataSet并没用到Ole接口    
  不会吧.你自己看源码,ClientDataSet是离不开COM   接口的.  
   
  关于类似的问题,   其实早有贴子已经讨论得比较成熟了.  
  可以参见  
  http://www.csdn.net/expert/topic/177/177973.shtm  
   
  Top

18 楼halfdream(哈欠)回复于 2001-12-02 19:33:42 得分 0

在线程创建CONNECTION连接(socket或DCOM)是必须的.  
  超过一个线程,  
  CoInitializeEx   不是最好要用..而是必须要用.  
   
   
  Top

相关问题

  • 关于线程使用lock
  • 如何使用线程?
  • 如何使用线程
  • 困惑:子线程如何使用主线程的变量?
  • UI线程能够使用线程池么?
  • 在线程中使用CSOCKET的问题?
  • 在线程中使用CSOCKET报错,Y?
  • 在C++ BUILDER 中如何使用线程?
  • 在线程中能否使用Timer????
  • 如何在 VB 中使用多线程?

关键词

  • 线程
  • 服务器
  • 执行
  • 接口
  • 数据
  • 连接
  • tclientdataset
  • fcds
  • trdabc
  • clientdataset

得分解答快速导航

  • 帖主:Crob
  • Miracle

相关链接

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

广告也精彩

反馈

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