3

TADOConnection内側にスレがあります。データベースへの接続に失敗した場合 (タイムアウト)、アプリを閉じるときにスレッドが停止し、アプリを閉じる前に試行が完了するまで時間がかかります。接続の接続タイムアウトを減らしたくありませんが、これは問題ではありません。接続の試行を強制的に中止する方法はありますか?

TADOConnectionはスレッド実行の開始時に接続し、成功するまで繰り返し自動的に再接続します。次に、アプリケーションを閉じるときに、データベースが接続に失敗している場合、スレッドは接続の試行が完了する (タイムアウトする) までハングします。

編集

これは、スレッドがどのように機能するかのサンプルです。

procedure TMyThread.Init;
begin
  CoInitialize(nil);
  FDB:= TADOConnection.Create(nil);
  FDB.LoginPrompt:= False;
  FDB.ConnectionTimeout:= 5;
  FDB.ConnectOptions:= coAsyncConnect;
end;

procedure TMyThread.Uninit;
begin
  if FDB.Connected then
    FDB.Connected:= False;
  FDB.Free;
  CoUninitialize;
end;

function TMyThread.Reconnect: Boolean;
begin
  Result:= False;
  if FDB.Connected then
    FDB.Connected:= False;
  FDB.ConnectionString:= FConnectionString;
  try
    FDB.Connected:= True; //How to abort?
    Result:= True;
  except
    on e: exception do begin
      //MessageDlg(e.Message, mtError, [mbOK], 0);
      FDB.Connected:= False;
      Result:= False;
    end;
  end;
end;

procedure TMyThread.Process;
begin
  if Reconnect then begin //Once connected, keep alive in loop
    while FActive do begin
      if Terminated then Break;
      if not Connected then Break;

      //Do Some Database Work

    end;
  end else begin
    //Log connection failure
  end;
end;

procedure TMyThread.Execute;
begin
  while not Terminated do begin
    if FActive then begin
      Init; //CoInitialize, create DB, etc.
      try
        while (FActive) and (not Terminated) do begin
          try
            Process; //Actual processing procedure
          except
            on e: exception do begin
              //Record error to log
            end;
          end;
        end;
      finally
        Uninit; //CoUninitialize, destroy DB, etc.
      end;
    end;
  end;
end;

(質問に関連するものだけを含めようとしました)

4

1 に答える 1

2

最初に頭に浮かぶのは、接続のタイムアウトを減らすことです。なぜあなたはそれを望まないのですか?また、アプリケーションを閉じるときに接続を確立する必要があるのはなぜですか? 特に、予想よりも時間がかかるときに中止したい場合は、接続する必要はありません。より多くの背景情報を知ることができたようです。

すぐに接続するという条件で本当に必要な特別なケースで、この問題がアプリケーションの破壊にのみ適用される場合は、スレッドが終了するまで待たないことをお勧めします。それを解放せずにアプリケーションを終了し、Windows にすべてのスレッドを含むプロセスを強制終了させます。

接続成功した場合、このアプローチは逆効果になる可能性があるため、スレッドが接続されたときにメインスレッドにシグナルを送り、スレッドを待って終了を延期します。そのためにもう一度タイムアウトが必要になる場合があります。

編集:

OnWillConnect接続を試みるたびにイベントが発生すると思います。EventStatus := esCancelそのハンドラ内で戻ってみてください。

于 2013-01-19T17:21:08.850 に答える