Отменить попытку подключения ADO Connection?

У меня есть 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;

(Пытался включить только актуальные вещи в вопрос)

1 ответ

Решение

Первое, что приходит на ум, - это уменьшить время ожидания соединения. Почему ты не хочешь этого? И почему вы хотите установить соединение при закрытии приложения? Особенно, если вы предпочитаете прервать его, когда это занимает больше времени, чем ожидалось, зачем вообще подключаться? Похоже, мы могли бы узнать больше информации.

В особом случае, когда он вам действительно нужен, при условии, что он быстро соединяется, и когда эта проблема относится только к уничтожению приложения, тогда я предлагаю не ждать окончания потока. Только не освобождайте его, закрывайте приложение и позволяйте Windows уничтожать процесс, включая все его потоки.

В случае, если соединение действительно успешно, тогда этот подход может иметь неприятные последствия, поэтому сигнализируйте вашему основному потоку, когда поток соединяется, и откладывайте его завершение, все еще ожидая потока. Вам может понадобиться еще один тайм-аут для этого снова.

Редактировать:

Я полагаю OnWillConnect событие будет происходить каждый раз при попытке подключения. Попробуй вернуться EventStatus := esCancel в своем обработчике.

Другие вопросы по тегам