【发布时间】:2012-02-15 01:11:01
【问题描述】:
我正在 Delphi XE2 中构建一个多线程 Windows 服务应用程序,它使用 ADO 数据库组件连接到 SQL Server。在线程内部之前我已经多次使用CoInitialize(nil);,但在这种情况下,我有一个我不确定的函数。
此函数称为TryConnect,它尝试使用给定的连接字符串连接到数据库。它在连接成功时返回 true 或 false。问题是这个函数会在主服务线程内部和外部使用,它会创建自己的临时TADOConnection组件,这需要CoInitialize...
我的问题是我还需要在这个函数中调用CoInitialize 吗?如果我这样做,并且由于服务的执行过程也使用CoInitialize,如果我从服务中调用此函数,它们会干扰吗? TryConnect 函数位于从主服务线程创建的对象内部(但最终将移至其自己的线程)。我需要知道从同一个线程(和CoUninitialize)调用CoInitialize() 两次是否会干扰 - 以及如何正确处理这种情况。
下面是代码...
//This is the service app's execute procedure
procedure TJDRMSvr.ServiceExecute(Sender: TService);
begin
try
CoInitialize(nil);
Startup;
try
while not Terminated do begin
DoSomeWork;
ServiceThread.ProcessRequests(False);
end;
finally
Cleanup;
CoUninitialize;
end;
except
on e: exception do begin
PostLog('EXCEPTION in Execute: '+e.Message);
end;
end;
end;
//TryConnect might be called from same service thread and another thread
function TDBPool.TryConnect(const AConnStr: String): Bool;
var
DB: TADOConnection; //Do I need CoInitialize in this function?
begin
Result:= False;
DB:= TADOConnection.Create(nil);
try
DB.LoginPrompt:= False;
DB.ConnectionString:= AConnStr;
try
DB.Connected:= True;
Result:= True;
except
on e: exception do begin
end;
end;
DB.Connected:= False;
finally
DB.Free;
end;
end;
所以为了澄清它真正在做什么,我可能会遇到这样的情况:
CoInitialize(nil);
try
CoInitialize(nil);
try
//Do some ADO work
finally
CoUninitialize;
end;
finally
CoUninitialize;
end;
【问题讨论】:
-
你阅读STAs上的文章了吗?使用
CoInitialize()意味着您拥有 STA。必须为每个线程初始化 COM,并且必须平衡CoInitialize()/CoUnitialize()调用。我不知道这在 Delphi 中是如何工作的,但您可能还必须在那里的线程之间编组指针。
标签: multithreading delphi activex ado delphi-xe2