16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"マルチスレッド対応COMサーバ"
この発言に対し以下のコメントが寄せられています
#01306 TN さん RE:マルチスレッド対応COMサーバ
アウトプロセスなCOMサーバで、複数のプロセス、スレッドから同時にメソッド
呼び出しを受け付けるためには、Application.Initializeの前に CoInitFlags
を COINIT_MULTITHREADED にして、プライマリスレッドをマルチスレッド
アパートメントに入れておかなければなりません。
これを設定しないとクライアントからのメソッド呼び出しがすべてシリアライズ
されてしまい、COMサーバのメソッドの中で「待ち」が入ると、他のスレッド、
プロセスからのメソッド呼び出しが全部待たされてしまいます。
COM とマルチスレッドの関係は非常にややこしくて頭痛いところ。
クライアントとサーバが別プロセスの場合、サーバ側のスレッドとクライアント側
のスレッドはそれぞれ独立したアパートメントであり、アパートが不適切だと
おのおのでシリアライズされてしまうようで、サーバクライアント両方の
プロセスの中で
「スレッドを正しくCOM のアパートに入れる」
必要があるようです。
参考文献:
http://www.borland.co.jp/delphi/papers/com/index.html
(注)
・ciMultiInstance を指定すると言うことはマシン上で
「ただ一個のサーバプロセス(オブジェクト)が生成される」
という意味になる。言葉が反対じゃないかと思うのだが、そういうことに
なっている
・サーバ側はD5ではCoInitFlagsを設定する必要は無い由
//////////////////////////////////////////////////////////////
// サーバ側のコード(自動生成されるユニット)
initialization
CoInitFlags := CoInitFlags and COINIT_MULTITHREADED; //追加
TAutoObjectFactory.Create(ComServer, TMyServer, Class_MyServer,
ciMultiInstance, tmFree);
//////////////////////////////////////////////////////////////
// クライアント側のコード(初期化のところで生成する場合)
var MyServerObject: IMyServer;
initialization
CoInitializeEx(nil, COINIT_MULTITHREADED);
MyServerObject := CoMyServer.Create;
finalization
// CoUnInitialize; を呼ぶとしぬ
//////////////////////////////////////////////////////////////
// クライアント側のコード(Application.Initializeのあとで生成する場合)
var MyServerObject: IMyServer;
procedure TForm.OnCreate(....
begin
if MyServerObject = nil then
MyServerObject := CoMyServer.Create;
.....
initialization
CoInitFlags := CoInitFlags and COINIT_MULTITHREADED;
TN(CQJ01721)
- FDELPHI MES(16):玉石混淆みんなで作るSample蔵【見本蓄積】 01/03/25 -
Original document by TN 氏 ID:(CQJ01721)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|