如题
我在调用一个远程方法的时候,因为执行时间过长。客户端在等待结构时候,如果拖拉窗口会变得空白一片,再点就无法响应了。
所以现在想改在多线程中执行这个过程。
但我在多线程中调用的时候提示
error reading from socket
如果再次执行就会提示
Invalid variant operation
不知道如何解决,请高手指教在多线程中调用远程方法的办法。
我在调用一个远程方法的时候,因为执行时间过长。客户端在等待结构时候,如果拖拉窗口会变得空白一片,再点就无法响应了。
所以现在想改在多线程中执行这个过程。
但我在多线程中调用的时候提示
error reading from socket
如果再次执行就会提示
Invalid variant operation
不知道如何解决,请高手指教在多线程中调用远程方法的办法。
dm.SC1.AppServer.UpYHData('user');
unit mheadyh;interfaceuses
Classes,adodb,activex,SysUtils;type
LinkServer = class(TThread)
private
protected
procedure Execute; override;
procedure showmsg;
public
constructor Create(Suspended:Boolean);
end;
var
msg:string;
implementationuses uyhuserinfrm,uDM;constructor linkserver.Create(Suspended:Boolean);
begin
FreeOnTerminate:=True;
inherited Create(Suspended);
end;procedure Linkserver.showmsg;
begin
yhuserinFrm.Memo1.Lines.Add(msg);
end;procedure LinkServer.Execute;
var
d1:Tdatetime;
begin
d1:=now;
try
Activex.CoInitialize(nil);
msg:='开始导入用户优惠数据库文件';
Synchronize(showmsg);
msg:=dm.SC1.Address; Synchronize(showmsg);
dm.SC1.AppServer.UpYHData('user');
except
on E: Exception do begin
msg:= '有错发生:'+e.Message ;
Synchronize(showmsg);
end;
end;
msg:='完成,耗时:'+formatdatetime('hh:mm:ss zzz',now-d1);
Synchronize(showmsg);
Activex.CoUninitialize;
end;end.
然后在子线程中用CoGetInterfaceAndReleaseStream把传进来的IStream散集为你原来的接口
然后该接口就可以在子线程中使用了
住:你的AppServer其实是IDispatch类型,你可以进行强转
你写的太高深了,看不懂,能不能把关键代码写出来,让我抄一下
var
stm: IStream;
disp: IDispatch;
AppServer: Variant;
begin
stm := IStream(Param);
CoGetInterfaceAndReleaseStream(stm, IDispatch, disp);
AppServer := disp;
AppServer.MyFunc;
Result := 0;
end;procedure TForm1.FormCreate(Sender: TObject);
var
ThreadId: Cardinal;
stm: IStream;
begin
CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer, stm);
BeginThread(nil, 0, ThreadFun, Pointer(stm), 0, ThreadId);
end;
我使用你的方法,编译没有问题。
但执行时提示:不支持此接口。
是何原因。
问问题要尽量提供多一点的线索,譬如执行到哪一句提示的,那个语句前后的东西是怎么写的
CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer, stm);
换成
CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer as IDispatch, stm);
unit mheadyh;interfaceuses
Classes,adodb,activex,SysUtils,ComObj,midas;type
LinkServer = class(TThread)
private
FStream: Pointer;
protected
procedure Execute; override;
procedure showmsg;
public
constructor Create(Suspended:Boolean);
end;
var
msg:string;
implementationuses uyhuserinfrm,uDM;constructor linkserver.Create(Suspended:Boolean);begin
FreeOnTerminate:=True;
OleCheck(CoMarshalInterThreadInterfaceInStream(IDispatch,dm.SC1.GetServer as IDispatch,IStream(FStream))); inherited Create(Suspended);
end;procedure Linkserver.showmsg;
begin
yhuserinFrm.Memo1.Lines.Add(msg);
end;procedure LinkServer.Execute;
var
d1:Tdatetime;
disp: IDispatch;
AppServer: Variant;
begin
d1:=now;
try
OleCheck(CoInitialize(nil));
msg:='开始导入用户优惠数据库文件';
Synchronize(showmsg); OleCheck(CoGetInterfaceAndReleaseStream(IStream(FStream), IDispatch, disp));
AppServer := disp;
AppServer.Cr_YH_fenlei('USER'); except
on E: Exception do begin
msg:= '有错发生:'+e.Message ;
Synchronize(showmsg);
end;
end;
msg:='完成,耗时:'+formatdatetime('hh:mm:ss zzz',now-d1);
Synchronize(showmsg);
CoUninitialize;
end;end.
这次提示成了英文了
就是执行到
OleCheck(CoMarshalInterThreadInterfaceInStream(IDispatch,dm.SC1.GetServer as IDispatch,IStream(FStream)));
时出的错
我把代码粘贴上来啦,看上面
“不支持此接口”是CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer, stm)提示的,意思是SocketConnection1.GetServer不支持IDispatch接口
觉得很怪,你自己试试吧,要么把IDispatch换成IAppServer,要么用你自己定义的那个接口,如果是你自己定义的那个接口,你需要引用那个tlb文件