我想用多线程来进行查询。但是不知道如何写线程的 execute() 方法,我查询主要要做 4 件事情:ClientDataset1: TClientDataset;
List1: TList;1 OpenDataSet;   //ClientDataset1.open;
2 GetOneRecord;  //将ClientDataset1中的一条记录(转为指针)存放到 List1 中。
3 MoveDataSet;   //ClientDataset1.Next;
4 DisPlayResult; //将查询结果显示在 ListView 上。
                 //ListView.OwnerData := True 处理 OnData() 事件来显示我想了很久,不知道怎么写线程类的 execute 方法才最合理。大家帮我看看吧!

解决方案 »

  1.   

    那具体怎么做呢?
    主要是如何写那个 Execute() 方法里面的那个循环,那哪些需要同步,哪些不需要,如何组织才最合理!
      

  2.   

    outer2000(天外流星):
      非常谢谢您的关注,
      如果您见到,可以进来详细说说吗?
      

  3.   

    查询取到数据集后,每读一记录,用POSTMESSAGE(注意,不是SENDMESSAGE),POSTTHREADMESSAGE之类的方法发一个自定义消息,在主线程消息事件里面加入LISTVIEW。
    这样避免你查询线程去直接访问LISTVIEW。
      

  4.   

    最好查询结果写到动态创建的TLISTVIEW中去,然后一次ASSIGN给FORM上的LISTVIEW;
      

  5.   

    数据库的动态查询要记住每一条线程都需要一个DATABASE和TSESSION对象。
    同意 outer2000(天外流星)的说法,使用动态创建组件的方式来实现,这样就不用VCL同步了,不过对主线程和分支线程都要用的VCL控件一定要同步。
    其实具体做法很简单,如果你的查询任务很单一和固定的话,直接在线程的执行方法中进行数据库控件的创建和销毁,除了这些不同外,和一般的查询一致,还有就是将查询出来的数据放入显示控件中,这个可能需要在线程创建函数中传入一个显示控件。
      

  6.   

    看看我的文章
    http://www.csdn.net/develop/Read_Article.asp?Id=16953
    应该是你要的
      

  7.   

    TO: wxjh你这篇文章里面有几个地方有误。
    1, 你把 CoInitialize( nil );加入的是线程对象CREATE事件中。线程的这个创建事件
    是在创建者线程中执行,如果主线程创建线程对象,这个CoInitialize实际在主线程。
    应该把CoInitialize放在线程对象EXECUTE函数的开始。你文章里面那个工作线程实质上没有调用coInitialize,但是为什么不出错了?这是因为
    里面有另一个错误,见下面2。2,Synchronize(ShellexeQuery);//你把所有可能不同步的东西一股脑都同步了,
    也就是实质上这个地方让它单线程运行,这样就算Coinitlialize没有正错运行,它
    也可以用。但只是可以用而已,完全没有多线程的好处了。
    只在万一得已的情况下才做同步,主要是象访问显示的GDI对象的时候需要。
      

  8.   

    谢谢各位!halfdream(哈欠):
        "把所有可能不同步的东西一股脑都同步了,也就是实质上这个地方让它单线程运行"
        您说得很对,我见过很多人写的多线程查询,都存在上面所说的问题,把可能不会产生冲突的方法也进行同步,实质等于是单线程,而事实上比单线程好一点点!
        您上面说的通过发送消息将结果写到界面上,我正是这么做的,最让我头痛的是如何写线程类的 Execute 方法,怎么写才合理,真正做到多线程!
        我想了很久了,还是不太明白,您教教我好吗?
      

  9.   

    放置ClientDateSet和对应的连接组件在一个数据模块上面,
    procedure TMyThread.Execute;
    begin
      { Place thread code here }
           CoInitialize(nil);//也可以用
        try
          DM:=DM.Create;
          如果要加commandText什么的,可以作为线程对象的成员传入..
          DM.ClientDataSet.Open;
          ........   
          ........
          这儿不一定要一条记录一条的POST消息.
          因为可以把ClientDataSet.Data值一次给出去.这样只要POST一条消息.
         
        finally
          DM.Free; //这儿要注意,因为DM要释放,所以查询回的数据要在这之前保存在其它地方.
          CoUninitialize;
        end;end;
      

  10.   

    halfdream(哈欠) :
      //这儿不一定要一条记录一条的POST消息.
      //因为可以把ClientDataSet.Data值一次给出去.这样只要POST一条消息.
      你这句如何理解?
      我想在界面上显示一个进度条,同时显示已经查询出多少条这样样的提示信息,你这样可以做到吗?  我测试过,下面两步比较消耗时间:
      1 从数据库里面取出数据,然后传回客户端,也就是返回数据集 ClientDataSet ,
      2 取出数据,显示在 ListView 上
      
      其他特别耗时间的地方我不太清楚,  我的疑惑是:我把查询到显示分为4个小方法来做,就像我在问题中所说的,如何组织这几个过程,哪些应该同步,哪些不需要,从而充分发挥多线程的优势,尽可能的合理分配处理机,因为,为了提高效率,有时候并不是不会访问Vcl的就一定在子线程中执行的,也可以放到主线程中去执行的。
      你再给我讲讲吧!
      

  11.   

    ringotu(Ringo),
      谢谢你的关注!
      你不留下 email ,我怎么给你电子邮件?你有什么好的想法?