【问题标题】:Cancel an ADO Connection's attempt to connect?取消 ADO 连接的连接尝试?
【发布时间】:2013-01-19 14:40:01
【问题描述】:

我在一个线程中有一个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;

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

【问题讨论】:

  • 您可以使用异步连接并在连接过程中调用TADOConnection.Cancel。我不确定是否有办法在同步模式下中断连接过程。
  • @TLama 谢谢,似乎合乎逻辑,所以我尝试了,将ConnectOptions 更改为coAsyncConnect 并在Stop 过程中添加FDB.Cancel(这会阻止线程中发生的任何事情)-没有运气:(
  • 当我调用TADOConnection.Cancel 时,线程仍然挂起,直到尝试完成,它在该行代码处暂停。
  • @TLama 你能用一个简单的例子来回答吗?我将编辑我的问题并在线程中放置一个如何使用数据库的示例。
  • @JerryDodge 我发现了同样的问题,但我必须找到solution for VB6(我们不能直接使用线程)。所以解决方案在“后台”使用定时器来取消连接。

标签: delphi timeout delphi-xe2 ado abort


【解决方案1】:

首先想到的是减少连接超时。你为什么不想要那个?以及为什么要在关闭应用程序时建立连接?尤其是当您希望在花费比预期更多的时间时中止它时,为什么还要连接呢?听起来我们可以知道更多的背景信息。

在你真正需要它的情况下,它连接很快,并且当这个问题适用于应用程序的销毁时,我建议不要等待线程完成。只是不要释放它,终止应用程序,然后让 Windows 终止进程,包括它的所有线程。

如果连接确实成功,那么这种方法可能会适得其反,所以当线程连接时向你的主线程发出信号,并通过等待线程来推迟它的终止。您可能需要再次超时。

编辑:

我想每次尝试连接时都会发生OnWillConnect 事件。尝试在其处理程序中返回 EventStatus := esCancel

【讨论】:

  • 我不想减少超时,因为如果连接失败,只要线程处于活动状态,它就会不断尝试连接。连接超时已经减少到 5 秒,在某些情况下实际上可能需要 4 秒来连接(因为这首先是在一个线程中)。仅当 a) 线程处于活动状态,b) 线程无法连接,以及 c) 用户尝试关闭应用程序(按此顺序)时,才会出现此问题
猜你喜欢
  • 2017-02-20
  • 2015-04-30
  • 2012-11-08
  • 1970-01-01
  • 2010-09-30
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多