0

我有一个进程外 COM 服务器,最初是在 Delphi 7 中开发的,然后是 D2006,最近在 XE3 下重新编译。在 XE3 版本下,一次处理一个请求。如果另一个进入时正在处理,则 ObjectCount 会增加,但直到第一个完成后才会处理第二个。D7/D2006 版本同时处理请求。

服务器维护一个数据库。大多数请求的处理速度非常快,但有些请求需要一分钟或更长时间。有一个带有备忘录的表单,它显示了一个活动日志,这就是整个 UI。不确定这里还有哪些其他信息会有所帮助。

任何想法为什么 XE3 版本会表现不同?或者,一般来说,为什么第二个服务器对象可能会等待第一个服务器对象完成?

这是一个例子。我安装了 XE5,创建了一个 VCL 应用程序,并使用一种方法添加了一个 COM 对象,并创建了一个测试客户端。它一次处理一个请求。我在 D2006 中编译了相同的项目(只需删除单位前缀)并同时处理它们。

我究竟做错了什么?

unit Unit2;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl;

type
  TTest = class(TTypedComObject, ITest)
  protected
    function Method1(N: Integer): HResult; stdcall;
  end;

implementation

uses ComServ;

function TTest.Method1(N: Integer): HResult;
var I: Integer;
begin
for I := 1 to N do
  Sleep( 1000);
end;

initialization
  TTypedComObjectFactory.Create(ComServer, TTest, Class_Test,
    ciMultiInstance, tmFree);
end.
4

2 回答 2

0

仔细检查每个版本的 COM 对象的线程模型。听起来 XE3 版本是单元线程(COM 序列化请求),而早期版本是多/自由线程(COM 不序列化请求)。

于 2013-10-30T16:16:07.887 回答
0

我通过上面简单的 Delphi XE5 服务器进行了跟踪。Application.Initialize -> ComServ.InitComServer -> ComObj.InitComObj -> CoInitializeEx(nil, COINIT_MULTITHREADED),返回 RPC_E_CHANGED_MODE。服务器一次处理一个请求。

跟踪D2006下编译的同一个项目,CoInitializeEx调用返回S_OK,服务器并发处理请求。

在调用 Application.Initialize 之前,我在项目源中添加了对 CoUninitialize 的调用。这样,XE5 版本可以同时处理请求。这也适用于提示问题的生产服务器。

于 2013-11-25T15:11:29.307 回答