我要从多个表(一个是本地表,其他四个是远程数据库中的表)中取回(select)一些数值,放到数据集中,在Grid中显示。本地表和远程数据库中的表,表的列(表结构)是一样的,只是数据不一致。本地表要比远程表快。所以我想在查询的时候用多线程,五个线程一起启动,本地表肯定先查完,就立即放在dataset中,在grid中显示,其他四个线程继续查询,查询结束后就把查询得到的数据加到 dataset里,在grid中刷新,以显示新查询到的数据。然后下一个线程继续。直至所有的查询进程全部完成。这样可以实现吗?高人提供点办法?

解决方案 »

  1.   

    谢谢 sanmaotuo(老冯) 。等代码看一下大侠风范谢 Elysium(東鱗覀爫) 这也是一种方法。
      

  2.   

    MARK  LOOK 1  XIA  CODE
      

  3.   

    unit DataSetMerge.MainForm;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, ADODB, Provider, StdCtrls, Grids, DBGrids, DBClient, Contnrs,
      DataSetMerge.QueryThread;type
      TMainForm = class(TForm)
        CDSLocal: TClientDataSet;
        CDSRemote_1: TClientDataSet;
        CDSRemote_2: TClientDataSet;
        CDSRemote_3: TClientDataSet;
        CDSRemote_4: TClientDataSet;
        DSPLocal: TDataSetProvider;
        DSPRemote_1: TDataSetProvider;
        DSPRemote_2: TDataSetProvider;
        DSPRemote_3: TDataSetProvider;
        DSPRemote_4: TDataSetProvider;
        DSLocal: TDataSource;
        DBGridLocal: TDBGrid;
        BRefresh: TButton;
        procedure BRefreshClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        FQueue: TQueue;
        FThreadsRunning: Integer;
        procedure ThreadDone(Sender: TObject);
        procedure WMQueryDone(var Msg: TMessage); Message WM_QueryDone;
      public
        { Public declarations }
      end;var
      MainForm: TMainForm;implementation{$R *.dfm}procedure TMainForm.FormCreate(Sender: TObject);
    begin
      FQueue := TQueue.Create;
    end;procedure TMainForm.BRefreshClick(Sender: TObject);
    begin
      BRefresh.Enabled := False;
      FThreadsRunning := 5;
      CDSLocal.Close;
      CDSRemote_1.Close;
      CDSRemote_2.Close;
      CDSRemote_3.Close;
      CDSRemote_4.Close;
      with TQueryThread.Create(DSPLocal, 0, Handle) do
        OnTerminate := ThreadDone;
      with TQueryThread.Create(DSPRemote_1, 1, Handle) do
        OnTerminate := ThreadDone;
      with TQueryThread.Create(DSPRemote_2, 2, Handle) do
        OnTerminate := ThreadDone;
      with TQueryThread.Create(DSPRemote_3, 3, Handle) do
        OnTerminate := ThreadDone;
      with TQueryThread.Create(DSPRemote_4, 4, Handle) do
        OnTerminate := ThreadDone;
    end;procedure TMainForm.WMQueryDone(var Msg: TMessage);
    begin
      case Msg.WParam of
      0: CDSLocal.Open;
      1: FQueue.Push(CDSRemote_1);
      2: FQueue.Push(CDSRemote_2);
      3: FQueue.Push(CDSRemote_3);
      4: FQueue.Push(CDSRemote_4);
      end;
    end;procedure TMainForm.ThreadDone(Sender: TObject);
    begin
      if CDSLocal.Active then
      begin
        while FQueue.AtLeast(1) do
        begin
          with TClientDataSet(FQueue.Pop) do
          begin
            Open;
            CDSLocal.AppendData(Data, True);
          end;
        end;
      end;
      Dec(FThreadsRunning);
      if FThreadsRunning = 0 then
        BRefresh.Enabled := True;
    end;end.--------------------------unit DataSetMerge.QueryThread;interfaceuses
      Classes, Messages, Provider, ADODB, ActiveX;const
      WM_QueryDone = WM_User+1010;type
      TTag = 0..4;
      TQueryThread = class(TThread)
      private
        FTag: TTag;
        FHandle: THandle;
        FQuery: TADOQuery;
        function CreateSQL(const Tag: TTag): string;
      protected
        procedure Execute; override;
      public
        constructor Create(const ADataSetProvider: TDataSetProvider; ATag: TTag; AHandle: THandle);
      end;implementationuses
      Windows, Forms, SysUtils;{ TQueryThread }constructor TQueryThread.Create(const ADataSetProvider: TDataSetProvider;
      ATag: TTag; AHandle: THandle);
    begin
      FTag := ATag;
      FHandle := AHandle;
      FQuery := TADOQuery.Create(nil);
      FQuery.ConnectionString := 'FILE NAME='+ExtractFilePath(Application.ExeName)+'\Merge.udl'; //写入链接串
      FQuery.SQL.Text := CreateSQL(FTag); //创建SQL语句
      ADataSetProvider.DataSet := FQuery;
      FreeOnTerminate := True;
      inherited Create(False);
    end;function TQueryThread.CreateSQL(const Tag: TTag): string;
    begin
      case Tag of
      0: Result := 'Select * From TWangs_UserInfo Where FUserID Like '+''''+'%%'+''''; //写入本地查询语句
      1: Result := 'Select * From TWangs_UserInfo Where FUserID Like '+''''+'02%'+''''; //写入远程查询语句
      2: Result := 'Select * From TWangs_UserInfo Where FUserID Like '+''''+'03%'+''''; //写入远程查询语句
      3: Result := 'Select * From TWangs_UserInfo Where FUserID Like '+''''+'04%'+''''; //写入远程查询语句
      4: Result := 'Select * From TWangs_UserInfo Where FUserID Like '+''''+'05%'+''''; //写入远程查询语句
      end;
    end;procedure TQueryThread.Execute;
    begin
      CoInitialize(nil);
      try
        FQuery.Open;
        PostMessage(FHandle, WM_QueryDone, FTag, 0); //发送查询结束消息
      finally
        CoUnInitialize;
      end;
    end;end.