2014-01-23 46 views
1

我有一个进程外com服务器,指定CLSCTX_LOCAL_SERVER作为上下文,REGCLS_MULTIPLEUSE作为连接类型。这会导致单个服务器进程被多个客户端的多个调用重用。进程外COM服务器 - 每个调用进程有一个服务器进程?

我现在想对服务器进行一些更改,但不幸的是无法使用客户端之间共享的单个进程(这是有原因的,但是他们很长时间)。我知道你可以设置服务器使用REGCLS_SINGLEUSE作为连接类型,这将为每次调用OOP服务器创建一个新的进程。这解决了我的问题,但在流程使用方面却不是首发;短时间内多次调用会导致很多进程,并且这个特定的服务器可能会经常遭遇难以置信的攻击。

有没有人碰巧知道混合这两种连接类型的机制?基本上我想要的是每个调用进程的单个服务器进程。 (即,客户端创建一个进程,并且该进程被重用于来自该客户端的后续调用,客户端2尝试调用服务器,并创建一个新进程)。我怀疑我可以通过强制REGCLS_SINGLEUSE服务器在客户端永久保持打开状态来实现它,但这既不优雅也不可能(因为我无法更改其中一个客户端)。

想法?

UPDATE 正如所料,似乎没有办法做到这一点。如果时间和资源允许,我很可能会将其转换为In-Proc解决方案。但现在,我不得不采用任何呼叫客户端使用的新行为。幸运的是,这种变化的影响非常小,并且被客户所接受。稍后我会研究更激烈和适当的更改。

注意 我已标记汉斯的答案回答,因为它事实上确实给一个解决的维护OOP解决的问题。我只是没有能力实施它。

cal

+0

所以你想要一个进程内解决方案的所有好处,而不需要它在进程内。这是对的吗?因为你所描述的每一个过程(这个过程中的“过程”)恰恰是这样做的,只有过程隔离是缺失的成分。 – WhozCraig

+0

到目前为止(这是遗留代码),我没有发现任何暗示,它确实需要过程中,并且我个人可能会使它处于进程中。不幸的是,这种改变的规模并不能证明在改变这种情况时需要进行的测试。就目前而言,我将新行为抹去了面向对象,并接受它稍微改变了老客户的行为。 – cal

+0

@cal,最好的解决方案是Hans提到的Application coclass。 – Ben

回答

5

COM不支持此激活方案。它应该被一个进程内服务器所覆盖,确保它不是你想要这样做的方式,因为它有相当大的优势。

使用REGCLS_SINGLEUSE是另一种选择,但这需要您扩展对象模型以避免您现在创建的服务器实例的风暴。 Application coclass是样板模式。为它提供工厂方法,为您的实例提供现有接口。

我会提到一个显着不同的方法,一个时候想解决同样的问题很好,但需要进程外的一个服务器采取桥接位数差距的优势我使用。您不会因COM为您启动服务器进程而陷入困境,客户端也可以启动它。当然,它对服务器的安装位置足够了解。现在客户端当然可以完全控制服务器实例。服务器用改变的CLSID调用CoRegisterClassObject(),我用进程ID对guid的一部分进行了存储。客户端做的一样,所以它总是与正确的服务器连接。客户端需要额外的代码才能确保它等待足够长的时间,以便服务器有机会注册其对象工厂。工作得很好。

+0

REGCLS_SINGLEUSE基本上是一个非启动器,代码本身可以很好地处理多个进程,但客户端可能会每秒多次触发该对象,从而创建一个不可接受的资源。 更激烈的方法可行,但我对客户的访问有点渺茫,其中两个已经发布。这个对象的设计有很多不足,不幸的是,测试资源不适用于更剧烈的变化。 – cal

+1

+1。先生,每个客户端的单个coclass服务器的创造力非常简单。 “这真棒!”接踵而至。当然不是正常的,但非常优雅。感谢那! – WhozCraig