如题
我在调用一个远程方法的时候,因为执行时间过长。客户端在等待结构时候,如果拖拉窗口会变得空白一片,再点就无法响应了。
所以现在想改在多线程中执行这个过程。
但我在多线程中调用的时候提示
error reading from socket
如果再次执行就会提示
Invalid variant operation
不知道如何解决,请高手指教在多线程中调用远程方法的办法。

解决方案 »

  1.   

    这样调用的
    dm.SC1.AppServer.UpYHData('user');
      

  2.   


    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.
      

  3.   

    在主线程中用CoMarshalInterThreadInterfaceInStream把接口列集为IStream,传到子线程中去
    然后在子线程中用CoGetInterfaceAndReleaseStream把传进来的IStream散集为你原来的接口
    然后该接口就可以在子线程中使用了
    住:你的AppServer其实是IDispatch类型,你可以进行强转
      

  4.   

    to lake_cx:
    你写的太高深了,看不懂,能不能把关键代码写出来,让我抄一下
      

  5.   

    function ThreadFun(Param: Pointer): Integer;
    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;
      

  6.   

    to lake_cx:
    我使用你的方法,编译没有问题。
    但执行时提示:不支持此接口。
    是何原因。
      

  7.   

    MyFunc换成你的UpYHData('user');
    问问题要尽量提供多一点的线索,譬如执行到哪一句提示的,那个语句前后的东西是怎么写的
      

  8.   

    或者你把
      CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer, stm);
    换成
      CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer as IDispatch, stm);
      

  9.   


    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.
      

  10.   

    to lake_cx:加了as IDispatch还是不行,提示interface not surport
    这次提示成了英文了
    就是执行到
    OleCheck(CoMarshalInterThreadInterfaceInStream(IDispatch,dm.SC1.GetServer as IDispatch,IStream(FStream)));
    时出的错
    我把代码粘贴上来啦,看上面
      

  11.   

    那把IDispatch全部换成你的Cr_YH_fenlei方法所在的接口
      

  12.   

    还是不懂,是不是 需要在客户端注册那个tlb类型库文件
      

  13.   

    “interface not surport”是dm.SC1.GetServer as IDispatch提示的,意思是dm.SC1.GetServer拿到的接口不是IDispatch类型
    “不支持此接口”是CoMarshalInterThreadInterfaceInStream(IDispatch, SocketConnection1.GetServer, stm)提示的,意思是SocketConnection1.GetServer不支持IDispatch接口
    觉得很怪,你自己试试吧,要么把IDispatch换成IAppServer,要么用你自己定义的那个接口,如果是你自己定义的那个接口,你需要引用那个tlb文件
      

  14.   

    应该不用引用你需要引用那个tlb文件这么麻烦吧
      

  15.   

    在线程里面使用TSocketConnection的时候,自己重新创建实例.