保持TAdoConnection活着

时间:2015-07-23 11:52:26

标签: sql-server delphi ado

在这里的一个问题: How can I detect that a TadoConnection lost the communication with the server?

建议创建一个Timer并轮询SQL服务器。

来自answer

  

TTimer没问题。查询应该在一个线程中执行,其中   使用相应的连接。虽然不是必须的,但它是一个   不同的问题。

我应该使用相同/主要连接(在主线程的DM中)还是应该在timer事件中创建 new 连接以“ping”SQL服务器?

轮询SQL服务器是否有助于保持连接处于活动状态?

1 个答案:

答案 0 :(得分:0)

使用计时器轮询连接是一个坏主意。进行不必要的民意调查会消耗资源,而且通常是应用程序设计的坏概念。

恢复断开连接的最佳方法是再次在try块中使用is,然后在except..end块内重新建立它。看看这段代码:

// Re-establishes connection every time it gets broken
procedure RespawnConnection;
begin
  FConnection := TADOConnection.Create(nil);
  FADODataSet := TADODataSet.Create(nil);
  with FConnection do
  begin
    ConnectionString := AdoConnectionString; // your CS here
    LoginPrompt := False;
    Connected := True;
  end;
  FADODataSet.Connection := FConnection;
end;

// An exposed method to do ADO queries
function Query(const sql: string): TADODataSet;
begin
  try
    Result := FADODataSet;
    FADODataSet.CommandText := sql; // if FADODataSet is not assigned,
                                    // this line throws an excepion...
    FADODataSet.Open;
  except
    RespawnConnection; // ...which is properly handled here...
    Result := Query(sql); // ...and then repeats the query
  end;
end;

不要忘记在FormClose事件中释放两个对象(除非它们是表单上的组件)。

如果耗时的查询,将整个ADO内容卸载到单独的线程可能是值得的。在用户体验方面,在单独的线程中运行此类查询将更有效。一旦const sql: string传递给一个线程,该线程将完成魔术,同时用户继续与主表单进行交互。

如果您要实现单独的线程概念,请不要忘记调用CoInitializeCoUninizialize,因为ADO基于COM(就像Jerry一样)并使用appartment-threaded对象。