私は、ADOデータベースコンポーネントを使用してSQL Serverに接続するDelphi XE2でマルチスレッドWindowsサービスアプリケーションを構築しています。私は内部スレッドの前にCoInitialize(nil);
を何度も使用しましたが、この場合、私は確信している機能を持っています。このシナリオではいつCoInitialize()を呼び出す必要がありますか?
この関数はTryConnect
と呼ばれ、指定された接続文字列でデータベースに接続しようとします。接続成功時にtrueまたはfalseを返します。問題は、この機能は、内側と外側の両方のメインサービススレッド外で使用されることがあり、それは
私の質問は、私はこの内のCoInitialize
を呼び出す必要はありませんですCoInitialize
を必要とし、独自の一時的なTADOConnection
コンポーネントを、...作成されます機能も?私がして、サービスの実行プロシージャはCoInitialize
も使用しているので、サービス内からこの関数を呼び出すと干渉しますか? TryConnect
関数は、メインサービススレッドから作成されたオブジェクトの内部にあります(ただし、最終的には独自のスレッドに移動されます)。同じスレッド(CoUninitialize
)から2回呼び出す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](http://msdn.microsoft.com/en-us/library/windows/desktop/ms680112(v = vs.85).aspx)の記事を読んだことがありますか? 'CoInitialize()'を使うと、STAがあることを意味します。 COMはすべてのスレッドに対して初期化されなければならず、 'CoInitialize()'/'CoUnitialize()'呼び出しのバランスをとる必要があります。私はこれがDelphiでどのように動作するのかわかりませんが、おそらくスレッド間のポインタを整列化する必要があります。 –