gpt4 book ai didi

multithreading - 在这种情况下什么时候需要调用 CoInitialize() ?

转载 作者:行者123 更新时间:2023-12-03 14:55:59 24 4
gpt4 key购买 nike

我正在 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;

因此,为了澄清它真正在做什么,我可能会遇到这样的情况:

CoInitialize(nil);
try
CoInitialize(nil);
try
//Do some ADO work
finally
CoUninitialize;
end;
finally
CoUninitialize;
end;

最佳答案

CoInitialize 必须在使用 COM 的每个线程中调用,无论它是什么线程,或者是否有父线程或子线程。如果线程使用 COM,则必须调用 CoInitialize

这里的正确答案是“视情况而定”。由于您知道服务线程已调用 CoInitialize,因此如果从服务线程调用 TryConnect,则无需再次调用。如果可以调用它的其他线程也调用了CoInitialize,则不需要调用它,因为该函数将在调用线程下运行。

MSDN文档专门解决了这个问题(强调):

Typically, the COM library is initialized on a thread only once. Subsequent calls to CoInitialize or CoInitializeEx on the same thread will succeed, as long as they do not attempt to change the concurrency model, but will return S_FALSE. To close the COM library gracefully, each successful call to CoInitialize or CoInitializeEx, including those that return S_FALSE, must be balanced by a corresponding call to CoUninitialize. However, the first thread in the application that calls CoInitialize with 0 (or CoInitializeEx with COINIT_APARTMENTTHREADED) must be the last thread to call CoUninitialize. Otherwise, subsequent calls to CoInitialize on the STA will fail and the application will not work.

所以答案是:如果您不确定,请调用CoInitialize。在 try..finally block 中执行此操作,并在 finally 中调用 CoUnitialize,或者在构造函数中初始化并在析构函数中取消初始化。

关于multithreading - 在这种情况下什么时候需要调用 CoInitialize() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9286600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com