Delphi COM服务器一次处理一个请求

时间:2013-10-30 11:33:29

标签: multithreading delphi com

我有一个最初在Delphi 7中开发的进程外COM服务器,然后是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.

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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版本同时处理请求。这也适用于提示问题的生产服务器。