取消ADO连接的尝试连接?

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;

(尝试只包含与问题相关的内容)


1
您可以使用异步连接并在连接正在进行时调用 TADOConnection.Cancel。我不确定在同步模式下是否有中断连接过程的方法。 - TLama
@TLama 谢谢,看起来很合理,所以我尝试了一下,将ConnectOptions更改为coAsyncConnect并在Stop过程中添加FDB.Cancel(停止线程中的任何操作)- 但没有成功:( - Jerry Dodge
当我调用TADOConnection.Cancel时,线程仍然挂起,直到尝试完成,它会暂停在那行代码上。 - Jerry Dodge
@TLama,您能否提供一个简单的示例答案?我将编辑我的问题并放置一个线程中如何使用DB的示例。 - Jerry Dodge
@JerryDodge 我发现了同样的问题,但我不得不为VB6找到一个解决方案(在那里我们不能直接使用线程)。因此,该解决方案使用计时器在“后台”取消连接。 - Francois Nel
1个回答

2
首先想到的是缩短连接超时时间。为什么不想这样做呢?为什么要在关闭应用程序时建立连接?特别是当您希望在连接时间超过预期时中止它时,为什么还要连接?听起来我们可能需要了解更多背景信息。
在特殊情况下,如果您确实需要在连接快速的条件下使用它,并且当此问题仅适用于应用程序的销毁时,那么我建议不要等待线程完成。只需不释放它,终止应用程序,让Windows杀死包括所有线程在内的进程即可。
如果连接成功,则此方法可能会产生反效果,因此当线程连接时向主线程发出信号,并通过等待线程来推迟其终止。您可能需要再次设置另一个超时时间。
编辑:
我认为每次尝试连接时都会触发"OnWillConnect"事件。在其处理程序中尝试返回"EventStatus := esCancel"。

我不想减少超时时间,因为如果连接失败,只要线程仍在运行,它就会不断尝试连接。连接超时已经被缩短到5秒钟,在某些情况下,实际上可能需要4秒钟才能连接(这是为什么首先将其放在线程中的原因)。只有当a)线程处于活动状态,b)线程无法连接,以及c)用户尝试关闭应用程序(按照这个顺序)时,才会出现此问题。 - Jerry Dodge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接