Jer*_*dge 6 delphi multithreading activex ado delphi-xe2
我正在Delphi XE2中构建一个多线程Windows服务应用程序,它使用ADO数据库组件连接到SQL Server.我CoInitialize(nil);
在内部线程之前已经使用了很多次,但在这种情况下,我有一个我不确定的函数.
调用此函数TryConnect
,尝试使用给定的连接字符串连接到数据库.它在连接成功时返回true或false.问题是这个函数将在主服务线程的内部和外部使用,并且它将创建自己的临时TADOConnection
组件,这需要CoInitialize
...
我的问题是我还需要调用CoInitialize
这个函数吗?如果我这样做,并且由于服务的执行程序CoInitialize
也使用,如果我从服务中调用此函数,它们会干扰吗?该TryConnect
函数位于从主服务线程创建的对象内部(但最终将移动到其自己的线程).我需要知道CoInitialize()
从同一个线程(和CoUninitialize
)调用两次是否会干扰 - 以及如何正确处理这种情况.
这是下面的代码......
//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;
Run Code Online (Sandbox Code Playgroud)
所以为了澄清它真正在做什么,我可能有这样的机会:
CoInitialize(nil);
try
CoInitialize(nil);
try
//Do some ADO work
finally
CoUninitialize;
end;
finally
CoUninitialize;
end;
Run Code Online (Sandbox Code Playgroud)
Ken*_*ite 14
CoInitialize
必须在每个使用COM的线程中调用,无论它是什么线程,或者它是否具有父线程或子线程.如果线程使用COM,则必须调用CoInitialize
.
这里的正确答案是"它取决于".由于您知道服务线程已调用CoInitialize
,因此如果TryConnect
从服务线程调用它,则不需要再次调用它.如果其他可以调用它的线程也调用了它CoInitialize
,则不需要调用它,因为该函数将在调用线程下运行.
在MSDN文档专门解决这个问题(强调):
通常,COM库仅在线程上初始化一次.在同一线程上对CoInitialize或CoInitializeEx的后续调用将成功,只要它们不尝试更改并发模型,但将返回S_FALSE.要正常关闭COM库,每次成功调用CoInitialize或CoInitializeEx(包括返回S_FALSE的调用)必须通过对CoUninitialize的相应调用进行平衡.但是,应用程序中调用CoInitialize为0的第一个线程(或CoInitializeEx与COINIT_APARTMENTTHREADED)必须是调用CoUninitialize的最后一个线程.否则,后续对STA上的CoInitialize的调用将失败,应用程序将无法运行.
所以答案是:如果你不确定,请致电CoInitialize
.做一个try..finally
块,并调用CoUnitialize
的finally
,或者在析构函数构造函数和未初始化初始化.
归档时间: |
|
查看次数: |
29110 次 |
最近记录: |