MTA问题中的进程外COM服务器

时间:2013-08-20 13:09:23

标签: delphi com mta

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

服务器按以下方式初始化。

情景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中创建服务器,并且在关闭期间没有错误,但客户端没有发现服务器的第一个实例,而是激活另一个实例。 / p>

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中初始化Server并绕过以下问题的建议:

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

1 个答案:

答案 0 :(得分:0)

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