【问题标题】:Out of process COM server in MTA issuesMTA 问题中的进程外 COM 服务器
【发布时间】:2014-12-26 21:00:35
【问题描述】:

我们有一个在 MTA 中运行的进程外服务器,它是一个带有 UI 的独立应用程序。

服务器通过以下方式初始化。

场景 1

initialization  begin
  CoUninitialize;
  CoUninitialize;
  CoUninitialize; //i have to call it three times to be able to initialize the MTA
  OLECHECK(ComObj.CoInitializeEx(nil, COINIT_MULTITHREADED));
  TAutoObjectFactory.Create(ComServer, MyServer,
     Class_MyServer,ciMultiInstance, tmFree);
end;

我只是启动应用程序,然后在没有任何客户端连接的情况下关闭。 在关闭期间发生以下错误:Runtime error 216 at 00408A2E 我无法追踪它,它似乎与 COM 有关,我认为我做错了什么。

如果我在 STA 中初始化服务器,则不会出现错误

initialization  begin
  TAutoObjectFactory.Create(ComServer, MyServer,
      Class_MyServer,ciMultiInstance, tmSingle);
end;

场景 2

我也尝试在初始化部分创建一个线程并在Thread.execute 中创建服务器,关闭期间没有错误,但客户端没有发现服务器的第一个实例而是激活另一个实例。

procedure TDCOMThread.Execute;
var dwReturn:DWORD;
    Msg:TMsg;
    H:THandle;
begin
    OleCheck(ComObj.CoInitializeEx(nil, COINIT_MULTITHREADED));
    TAutoObjectFactory.Create(ComServer, MyServer,
         Class_MyServer,ciMultiInstance, tmFree);
    H:=EVentStop.Handle;
    while true do
    begin
       dwReturn:=MsgWaitForMultipleObjects(1,H,false,200,QS_ALLINPUT);
       case dwReturn of
         WAIT_OBJECT_0: break;
         (WAIT_OBJECT_0+1): begin
             while PeekMessage(msg,0,0,0,PM_REMOVE) do
               Dispatch(Msg);
         end;
         WAIT_TIMEOUT:begin
                           while PeekMessage(msg,0,0,0,PM_REMOVE) do
                             Dispatch(Msg);
                        if Terminated then
                         break;
                      end;
         WAIT_FAILED:begin
              break;
         end;
         WAIT_ABANDONED:
         begin
           break;
         end;

       end;
    end;
    CoUninitialize;
end;

初始化部分

 initialization  begin
        EVentStop:=Tevent.Create(true);
        EVentStop.ResetEvent;
        DThread:=TDCOMThread.Create(true);
        DThread.Resume;
    end;

您能否就如何在 MTA 中初始化服务器并绕过以下问题提供任何建议:

  1. 关闭时不要报错
  2. 当手动启动服务器时,客户端不会启动服务器应用程序的另一个实例 - 当我使用线程初始化服务器时会出现此问题

【问题讨论】:

  • 如果你CoUninitialize 三次,你不应该Coinitialize 三次吗?其他人在你之前做过,下一个 CoUninitialize 预计只会递减,在你的情况下,如果会完全终止 MTA...
  • 场景 1 大错特错,不值得进一步考虑。您正在 Delphi 的 COM 基础架构下进行联合初始化。
  • 这就像炸毁建筑物下面的三层地基以安装管道。
  • 好的,我明白这是错误的方式。但是如何在 MTA 中初始化服务器是正确的。我已经尝试在单独的线程中但是如果服务器手动启动客户端启动另一个实例而不是连接到启动的一个。

标签: delphi com mta


【解决方案1】:

在场景 2 中,尝试从新创建的工厂调用 RegisterClassObject。 如果在主线程中创建工厂 - RegisterClassObject 会自动调用。

【讨论】:

  • 看起来像我的答案,解决选项'2'。
  • 几个月前我使用 CoRegisterClassObject 和 CoRevokeClassObject 解决了这个问题。这完全一样,所以我会接受答案为有效。
猜你喜欢
  • 2014-02-18
  • 2013-01-20
  • 2012-09-06
  • 1970-01-01
  • 2010-09-05
  • 2015-05-23
  • 2011-05-17
  • 2012-10-10
  • 2020-10-06
相关资源
最近更新 更多