在数据库操作时,系统像死掉了一样,所以,我想让用户能够随便移动一下图标、显示一个进度条等功能,如何才能做到呢?我记得在vb中有个do events语句,能实现类似功能,而delphi是什么方法呢?

解决方案 »

  1.   

    看TSession的帮助,看这方面的资料。其实加个TSession就差不多已经行了,只不过Query的open要在另一个线程中执行。Open的时候,不能有DBGrid(也就是数据感知控件啦)连上Query的DataSource。要用 TThread的Synchronize
    比如
    FQuery.Open;
                            Synchronize( SetDBGrid );
      

  2.   

    数据库操作用异步操作,
    完成时会有相应消息回来。
    比如说用AdoQuery.
    设置executeOptions
    AdoDataset.OnFetch事件中
    progress参数显示工作进度。
      

  3.   

    简单的很啊,你可以用Thread来编写嘛!不过要注意并发哦!
      

  4.   

    我的多线程查询例子。unit TQueryThread_Unit;interfaceuses
      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;implementationconstructor 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.使用的时候,先Create(费话!) ,这里Create给的是当前的form,然后指定SQL语句,SQL工作模式,还有显示SQL查询结果的DBGrid。    QueryThread := TQueryThread.Create (Self);
        QueryThread.DBGrid := DBGrid_Show ;
        QueryThread.SQLText :=Memo_SQL.Text ;
        QueryThread.SQLModel := SQLModel ; (指定SQL执行的模式)
        QueryThread.Resume ;关闲查询就先Suspend再Free,不这样做会出错。
            QueryThread.Suspend;
            QueryThread.Free;