客户端多线程访问DCOM服务器的问题(200分)

我苦

Unregistered / Unconfirmed
GUEST, unregistred user!
使用Automation Object编写一个DCOM服务器,服务器实现的功能是向主窗口添加由客户端
提交的一个字符串;采用Free线程模式,程序如下:
主窗口:
type
TForm1 = class(TForm)
Memo1: TMemo;
public
procedure AlertNotify(const AlertID:String);
end;
...
procedure TForm1.AlertNotify(const AlertID:string);
begin
Memo1.Lines.Add(AlertID)
end;

自动化服务器:
unit AlertNotifyIntf;
interface
uses
ComObj, ActiveX, AlertSrv_TLB, StdVcl;
type
TAlertNotifyIntf = class(TAutoObject, IAlertNotifyIntf)
protected
procedure SetAlertID(AlertID: OleVariant);
safecall;
end;

implementation
uses ComServ, UnitMain;
procedure TAlertNotifyIntf.SetAlertID(AlertID: OleVariant);
begin
Form1.AlertNotify(AlertID);
end;
initialization
TAutoObjectFactory.Create(ComServer, TAlertNotifyIntf, Class_AlertNotifyIntf,
ciMultiInstance, tmFree);
end.

客户端打算采用多线程,每个线程使用CoAlertNotifyIntf.CreateRemote函数创建远程
主机上的DCOM服务器对象,CoAlertNotifyIntf是自动化服务器创建的实现IAlertNotifyIntf
接口的对象类:
unit UnitAlertSendThread;
interface
uses
Classes,AlertSrv_TLB,SysUtils,ActiveX;
type
AlertIDSend = class(TThread)
private
{ Private declarations }
FRemoteMachineName:string;
FIAlertNotify:IAlertNotifyIntf;
protected
procedure Execute;
override;
public
constructor Create(const count:integer;
RMachine:string);
proceduredo
Terminate;override;
end;

implementation
uses
ComObj;
constructor AlertIDSend.
Create(const count:integer;
RMachine:string);
begin
inherited create(true);
FRemoteMachineName:=RMachine;
FIAlertNotify:=CoAlertNotifyIntf.CreateRemote(FRemoteMachineName);
FreeOnTerminate:=true;
end;

procedure AlertIDSend.
Execute;
var
AlertID:string;
begin
// CoInitialize(nil);
while not Terminateddo
begin
//给AlertID赋值,此处省略
FIAlertNotify.SetAlertID(AlertID);
end;

// CoUnInitialize;
end;
end.

线程的创建没问题,线程中IAlertNotifyIntf接口也顺利创建,只有当线程运行时,执行
接口中的方法:FIAlertNotify.SetAlertID(AlertID)时,程序报错:标记没有引用存储。
我试着在线程执行前添上CoInitialize(nil)方法,执行后报错:消息筛选器拒绝这个调
用。不知哪位大侠能帮我解决这个问题。要能够在客户端用多线程访问DCOM服务器。
 
搞懂了,原来是要在create这个DCOM对象前就调用CoInitialize(nil)。
将FIAlertNotify:=CoAlertNotifyIntf.CreateRemote(FRemoteMachineName);
挪到execute中即可,然后再进入线程循环就没问题了。
 
顶部