最近要做一个当adoquery查询时 做一个进度条 不知道怎么用多线程做.
注意 利用那个adoquery中的那个execute option属性的方法 不需要了
当然 是个假的进度条也可以,让人家觉得 不是死机了 就可以了不知道怎么做呀?请大虾给个简单的原码参考一下.还有一个问题,就是怎么让线程对象释放掉???
定义一个线程类:
mythread=class(tthread)
  ...
 ...
end;在一个按钮事件中:
var 
  aThread:mythread;
begin
  aThread:=mythread.create;
  aThread.Free;//如果就这样释放掉,好象并没有执行execute过程中的程序
  //要怎么样释放掉呢???
end;

解决方案 »

  1.   

    在excute中写一个死循环,在循环中显示,如果要显示vcl需要同步函数,以syn开头的。然后在查询结束后释放。
      

  2.   

    把查询的功能写在线程里面,这样在查询的时候就不会出现假死的情况了,这样进度条你也可以写在Timer里面.
    aThread:=mythread.create; 
    aThread.Free;
    这样说话execute应该会被执行一次,不过具体得测试一下,在线程的构造函数里面通常会调用父类的create方法,inherited create(CreateSuspended);CreateSuspended为Boolean类型,如果会true时创建线程对象的时候就会执行execute方法,如果为false就不执行.如果你想执行完execute方法后就自动free可以,在设置FreeOnTerminate := true;这里执行完线程对象会自动释放.
      

  3.   

    其实也很简单
    下面是我利用线程处理考勤数据的,一次处理一个员工,然后进度条显示百分比。和楼主需求一样吧1:点击"按钮"
       Thread:=CreateThread(nil,0,@ExecThread,nil,0,wd);2:procedure ExecThread;stdcall;
       var
          v_str:string;
    begin
       try
          CountFrm.qryFind.Close;
          CountFrm.qryFind.Parameters.ParamByName('gh').Value:=CountFrm.ComPersonel.Text;
          CountFrm.qryFind.Parameters.ParamByName('Dept').Value:=CountFrm.ComDept.Text;
          CountFrm.qryFind.Prepared;
          CountFrm.qryFind.Open;
          CountFrm.Gauge1.Visible:=true;
          CountFrm.Gauge1.MaxValue:=CountFrm.qryFind.RecordCount;
          CountFrm.Gauge1.Progress:=0;
          while not CountFrm.qryFind.Eof do
          begin
             v_str:='exec Check_Work..count_report '''','''+CountFrm.qryFind.fieldbyname('工号').AsString+''','''+datetostr(CountFrm.BeginDate.Date)+''','''+datetostr(CountFrm.EndDate.Date)+'''';
             CountFrm.qryEXEC.Close;
             CountFrm.qryEXEC.sql.Clear;
             CountFrm.qryExec.SQL.Add(v_str);
             CountFrm.qryExec.Prepared;
             CountFrm.qryExec.ExecSQL;         CountFrm.Gauge1.Progress:=CountFrm.Gauge1.Progress+1;
             CountFrm.qryFind.Next;
          end;
          CountFrm.Cursor :=crdefault;
          messagebox(CountFrm.handle,'执行成功!','提示',MB_ICONINFORMATION+MB_OK);
          CountFrm.Gauge1.Visible :=false;
          CountFrm.ComDept.Clear;
          CountFrm.ComPersonel.Clear;
          CountFrm.BeginDate.Date:=strtodatetime(formatdatetime('yyyy-mm-01',Getdate()));
          CountFrm.EndDate.Date:=Getdate();
          CountFrm.BitBtn1.Enabled :=true;
          CountFrm.BitBtn2.Enabled :=true;
       except
          CountFrm.Gauge1.Progress:=0;
          CountFrm.Gauge1.Visible:=false;
          CountFrm.BitBtn1.Enabled :=true;
          CountFrm.BitBtn2.Enabled :=true;
          MessageBox(CountFrm.Handle,'在数据处理过程中出现问题,请与系统员联系!','提示',MB_ICONWARNING);
       end;end;
      

  4.   

    后来我这么做:
    线程1:
    如果标志查询完成的变量(工程中定义的一个全局变量)=false
    表示没有完成,那么进度条位置增加;如果查询完成,则线程1释放.线程2:
    执行查询语句,执行完成后,就释放掉在工程的按钮事件中
    var
      thread1:线程1;
      thread2:线程2;
    begin
      bComplete:=false; //标识查询是否完成
      thread1:=线程1.create;
      thread2:=线程2.create;
      thread2.waitfor;
      bComplete:=true;
      
    end;
    程序会出现:system error code6 句柄无效.是不是我在 线程2 中,写了如果执行结束就自动 释放
    然后 程序中有thread2.waitfor
    所以会出现 那个错误??????
      

  5.   

    简单的事情复杂化了,两个建议:
    1、如果用线程的话,那就在执行SQL语句前创建线程,执行完SQL语句之后释放。
    2、也可以用Timer来刷新。
    用不到两个线程的。
      

  6.   

    简单的事情复杂化了,两个建议: 
    1、如果用线程的话,那就在执行SQL语句前创建线程,执行完SQL语句之后释放。 
    2、也可以用Timer来刷新。 楼上说的 那两个建议 好象不行哦
    如果用timer来刷新进度条的话,在查询语句执行的时候,进度条根本不会动,好象是卡机了那个样子1、如果用线程的话,那就在执行SQL语句前创建线程,执行完SQL语句之后释放
    这个方法,还不知道怎么做. 
    也不太明白具体怎么做?  
      

  7.   

    Timer的说错了,确实不会响应Time事件了,采用线程吧。
    线程里面只刷新进度条(Execute函数),在主线程里面执行SQL语句myThread := TMyThread.Create(FALSE);//线程中只刷新进度条即可,要调用同步函数
    //此处增加执行SQL的语句
    try
      wQuery.SQL.Text := 'SELECT * FROM sometable';
      wQuery.Open;
      while not wQuery.Eof do
      begin
        //do something...
        wQuery.Next;
      end;
    finally
      wQuery.Close;
      myThread.Free;
    end;
      

  8.   

    1。使用FreeONTerminate=True你就不用去释放了。
    2。可以创建TEvent来标记线程是否执行结束,如果你的主程序需要知道线程结束的话。
    3。如果希望自己释放线程,必须设置FreeONTerminate:=False.