Q&A

  • Tquery로 쿼리동중 강제종료 할 수 있나여?
안녕하세요?

질문할 내용은 다름이 아니라
Tquery로 쿼리를 할때 입니다.

만약에 서버로 쿼리해서 일정시간 동안 응답이 없으면 쿼리를 취소하려고 하거든요!

근디 제가 테스트 해본 바로는

TQuery.Open 명령을 내리면 프로세스를 독점하네여 ㅠㅠ
Open이 일어나고 있는 동안에는 다른 작업은 안먹히는 군여

Tquery 도 TimeOut 이런 속성이 있으면 좋으련만
이게 가능한건지 아시는 분이 있으면 알려주시면 감사하겠습니다.
3  COMMENTS
  • Profile
    skysoft 2003.10.29 02:59
    저도 해봤는데 중단 못 시키겠더군요.
    아시는 것처럼 쓰레드로 쿼리하는 방법이 대안이 될 거 같습니다.
    그러면 쿼리하는 중에도 다른 작업(타이머로 시간을 체크함)이 가능하더라고요.
    아래 사이트를 참조해서 코딩해봤습니다.
    쓰레드에서 쿼리는 자신만의 세션을 요함.

    http://bdn.borland.com/article/0,1410,16231,00.html

    ----------------------------------------------------------------------
    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, Grids, DBGrids, DBTables, Db, ExtCtrls;

    type
      TForm1 = class(TForm)
        DataSource1: TDataSource;
        Query1: TQuery;
        Database1: TDatabase;
        Session1: TSession;
        DBGrid1: TDBGrid;
        Button1: TButton;
        Button2: TButton;
        Timer1: TTimer;
        procedure Button1Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

      TQueryThread = class(TThread)
      private
        FSession: TSession;
        FDatabase: TDataBase;
        FQuery: TQuery;
        FDatasource: TDatasource;
        FQueryException: Exception;
        procedure ConnectDataSource;
        procedure ShowQryError;
      protected
        procedure Execute; override;
      public
        constructor Create(Session: TSession; DataBase:
          TDatabase; Query: TQuery; DataSource: TDataSource);
          virtual;
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.DFM}

    constructor TQueryThread.Create(Session: TSession; DataBase:
      TDatabase; Query: TQuery; Datasource: TDataSource);
    begin
      inherited Create(True);    // Create thread in a suspendend state
      FSession := Session;       // connect all private fields
      FDatabase := DataBase;
      FQuery := Query;
      FDataSource := Datasource;
      FreeOnTerminate := True;   // Have thread object free itself when terminated
      Resume;                    // Resume thread execution
    end;

    procedure TQueryThread.Execute;
    begin
      try
        { Run the query and connect the datasource to the TQuery
          component by calling ConnectDataSource from main
          thread (Synchronize used for this purpose)}
        FQuery.Open;
        Synchronize(ConnectDataSource);
      except
        { Capture exception, if one occurs, and handle it in the
          context of the main thread (Synchonize used for this
          purpose. }
        FQueryException := ExceptObject as Exception;
        Synchronize(ShowQryError);
      end;
    end;

    procedure TQueryThread.ConnectDataSource;
    begin
      FDataSource.DataSet := FQuery;  // Connect the DataSource to the TQuery
    end;

    procedure TQueryThread.ShowQryError;
    begin
      Application.ShowException(FQueryException); // Handle the exception
    end;

    procedure RunBackgroundQuery(Session: TSession; DataBase:
      TDataBase; Query: TQuery; DataSource: TDataSource);
    begin
      { Create a TThread instance with the various parameters. }
      TQueryThread.Create(Session, Database, Query, DataSource);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      DataSource1.DataSet := nil; //데이타소스는 나중에 쓰레드의 synchronize 부분에서 연결함
      Query1.Close;
      Query1.SQL.Text := 'select count(*) from tb_refnd ';
      RunBackgroundQuery(Session1, Database1, Query1, DataSource1);
      Timer1.Enabled := true;
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      Timer1.Enabled := false;
      ShowMessage('쿼리 시간 경과');
      DBGrid1.Visible := false; //쿼리결과를 보여주지 않음
    end;

    end.

  • Profile
    백진욱 2003.10.29 18:42
    답변해주셔서 정말 감사합니다. ^^

    한가지 더 질문이 있는데요 ^^;

    쓰레드를 사용했을 경우
    Form을 종료할 때 쓰레드가 실행중일 경우에
    에러가 발생하잖아여 ㅜ.ㅜ
    실행중인 쓰레드 프로세스를 죽일 방법은 없는지요?
    쓰레드만 죽이면
    완벽할것 같습니다. ^^

    수고하세요!
  • Profile
    skysoft 2003.10.29 20:27
    다시 원점으로 돌아온 느낌이네요.
    쿼리가 실행중일 때는
    쓰레드를 강제종료해도 에러가 나네요.
    쓰레드의 쿼리가 결국은 메인폼에 있는 쿼리고요.
    쓰레드에서 따로 쿼리를 create 해서 한다고 해도(?) 같은 결과를
    볼 거 같네요.
    연 쿼리를 강제로 닫는 문제로 다시 돌아왔네요.
    클라이언트단에서는 어려운 모양입니다.
    서버단에서 가능한 방법이 있을런지요.