我在CB5环境下用COM+开发了一个中间件,又做了一个测试客户端,事先建立COM+对象,然后点击一个按钮,调用COM+的一个方法,其实在COM+的方法中只做了空语句的三层循环,每层循环2000次。
测试结果单独调用一次COM+对象方法花费了18秒,
但同时(不可能绝对,大致同时,总由先后的)点击三个COM+客户端时花费的时间分别为54、54、54秒。
但我认为应当是顺序响应的,应当为18、36、54秒。听了猛禽兄的意见,我又用delphi6作了一次测试,发现也是如此,只不过响应时间加快了而已。就如同到银行排队取款,后来的人当然要多等些时候,但不能说随着后面来人增多,第一个人也需等着,最后大家同时拿到钱。
COM+的处理方式倒像是并发执行,但所有客户端都按最长时间被响应,我不能想象有100个客户会怎样。 有没有办法可以改变这种情况?
我用的是apartment模式

解决方案 »

  1.   

    D6中的COM+线程只有single,apartment,both三种,根据HELP里的解释,要实现你说的响应过程,还是试下single吧应。
      

  2.   

    我昨天回去试了一下,没有你说的情况啊。不过我是用客户端线程的,服务端的方法是Sleep(3000),客户端用三个线程同时调用服务端的方法,用DCOM方式时,三个线程的总时间是3.4s左右,用COM+方式时是3.1s左右,很正常啊。
      

  3.   

    COM+是Apartment模式,不支持事务。
      

  4.   

    俺的系统绝大部分用的是COM+,可没有你说的那么严重。除了第一次建立COM+对象时会慢一点外,后面的运行起来很快呀请贴一下你的代码吧
      

  5.   

    我选的是需要事务SERVERprocedure TTestCoSerTime.Method1(Test: Integer);
    var i,j,k:integer;
    begin
      for i:=1 to Test do
        for j:=1 to Test do
           for k:=1 to Test do
              ;
    end;clientvar
      obj:ITestCoSerTime;
    {$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
     stime,etime:ttime;
    begin
     stime:=Time;
     obj:=CoTestCoSerTime.CreateRemote('jkx-agan002');
     etime:=time;
     Edit2.Text:=formatDateTime('ss:zzz',etime-stime);
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
     stime,etime:ttime;
    begin
     stime:=Time;
     obj.Method1(StrToInt(Edit1.Text));
     etime:=time;
     Edit3.Text:=formatDateTime('ss:zzz',etime-stime);
    end;
    这是我在delphi 6中的写的代码
    edit1.text 为2000delphi 6的method1执行完毕时间比cb快,cb中单独一个客户端独立调用18秒,三个客户同时的结果为54,54,54, delphi中单独一个客户端独立调用6秒,三个客户同时的结果为18,18,18,我做这个测试的目的不是想说速度快慢,毕竟不会有人写三层的2000次循环,我只是对后来者导致先来者慢下来觉得不理解,(技术上可以理解,并发交叉分时间片执行就会这样,但com+这样设计有意义码??至少要向midas 中6秒,12秒,18秒这样吧,谁让你后来一步呢,只好等前面两个做完再说了,但早来至少不被影响啊)  
    我在实施不支持事务的看看
      

  6.   

    应该不会有这种事的,要不我回去用多个客户端进程再试试代码在家里,你留下MAIL,我晚上回家发
      

  7.   

    [email protected]
    先谢谢了
      

  8.   

    已发出,我刚又试着运行了三个实例,每个实例三个线程,只在第三个实例的第二个线程(就是连接的第八个COM+对象)开始变慢,也只用了6s
      

  9.   

    to 猛禽:
    看了你的代码,知道你我运行结果差异的原因了,
    因为当Test 为2000时
    for i:=1 to Test do
        for j:=1 to Test do
           for k:=1 to Test do
              ;
    在delphi 6中的耗时大概为6秒,所以我就对应假定你的sleep(6000)来说问题。
    由于sleep是不做事情的(不耗用cpu时间片),所以三个(或任意个)客户端同时调用com+对象方法时,耗时都是6秒,它们一点都不占用cpu,到六秒钟后,cpu 把几个对象唤醒就是了
    但对与
    for i:=1 to Test do
        for j:=1 to Test do
           for k:=1 to Test do
              ;
    而言,它们是实实在在的耗用了6秒的cpu时间,所以不管是串行顺序执行,还是并发交叉分时间片执行,都会耗用服务器的cpu时间为18秒(不考虑分时的额外耗时),只是不同的执行对客户端影响不同而已,串行则客户端为6,12,18,(后来者吃亏),并发则客户端为18,18,18,大家都一样
      

  10.   

    我的分析:
    并发的执行适应两种情况:
    1、用户需要频繁的舆系统交互,这样,大家就都可以慢慢的得到一步分信息,这样不至于后来等的太着急,最后大家同时得到完整的全部信息。(这适用于用户的速度比系统处理慢的多的情况,先来者感觉不到被独占cpu时间和分时占有cpu时间的差异,差异相对于用户速度而言太小了)这是一种假并行,服务器的cpu时间比串行顺序执行时间还长些(分时,进/线程转换的耗时,是为了满足用户的心理需要而言)
    2、方法中不只有计算(耗用cpu 时间),还有其他操作(如I/O),这样,当一个执行计算时,另一个做i/o,从而使各个部件都得到使用,这是一种真并行(真并行必须要有多个物理设备)。
    所以,我的例子举的有点特殊,因为它只有计算,所以这样并发(cpu 分时)起来,大家都慢起来了,因此就没任何意义了。
    由此我想到,实际的系统中往往要做数据处理,处理计算之外,必然要进行i/o,com+这样处理,对客户端确实还是造成了后来者对先来者的影响,但对于服务器达到了各设备的最大吞吐量,是不是好些(由于不止有cpu,还有其他设备部件),这样完成所有客户的任务的总时间比串行的要短些。
    所以我将method1中的方法改为将一个大文件拷贝到另一个大文件(不同的客户端,这个目标文件不同)中去,结果发现还是老样子,每个客户端调用method1的耗时(time)总是等于单个客户端调用耗时*客户端数目我想:如果 (单个客户端调用耗时) <  time  < (单个客户端调用耗时*客户端数目),也算对服务器端有意义啊,现在算什么呢?(或许是我的i/o处理举例不是太好?没能充分利用各设备间的并行?ado和sql server在这里处理的比较好?)或许是我是在一台机器上作的测试,如果再网络中测试,可能由于网络速度的问题,在第二个客户端要求到达服务器之前,第一个客户端的要求已经做完了?不知道是否有用com+做过实际系统的大虾,说一下实际的运行和网络设置情况如何?举例:20 个客户端的系统是正常的吧,一个com+对象方法执行1秒也是正常的吧,但按照上述测试,20个客户端同时调用执行1秒的方法,会怎么样?都等待20秒?
      

  11.   

    建议你将METHOD改为执行一个复杂查询(最好数据库在另一台机器),这样接近实际的情况。
    我估计应该在我们的结果之间。因为一部分工作是由数据库服务器做了。