Я создаю многопоточное приложение для Windows-приложений в Delphi XE2, которое использует компоненты базы данных ADO для подключения к SQL Server. Я использовал CoInitialize(nil);
много раз перед внутренними потоками, но в этом случае у меня есть функция, о которой я не знаю.Когда мне нужно вызвать CoInitialize() в этом сценарии?
Эта функция называется 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;
Вы прочитали статью о [STAs] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms680112 (v = vs.85) .aspx)? Использование 'CoInitialize()' означает, что у вас есть STA. COM должен быть инициализирован для каждого потока, а 'CoInitialize()'/'CoUnitialize()' вызовы должны быть сбалансированы. Я не знаю, как это работает в Delphi, но вам, вероятно, придется маршевать указатели между потоками. –