在这里的一个问题: How can I detect that a TadoConnection lost the communication with the server?
建议创建一个Timer并轮询SQL服务器。
来自answer:
TTimer没问题。查询应该在一个线程中执行,其中 使用相应的连接。虽然不是必须的,但它是一个 不同的问题。
我应该使用相同/主要连接(在主线程的DM中)还是应该在timer事件中创建 new 连接以“ping”SQL服务器?
轮询SQL服务器是否有助于保持连接处于活动状态?
答案 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
传递给一个线程,该线程将完成魔术,同时用户继续与主表单进行交互。
如果您要实现单独的线程概念,请不要忘记调用CoInitialize
和CoUninizialize
,因为ADO基于COM(就像Jerry一样)并使用appartment-threaded对象。