【问题标题】:How to call release from COM server如何从 COM 服务器调用 release
【发布时间】:2012-05-22 18:32:48
【问题描述】:

我正在编写一个 Com 服务器,并且我编写了检测 COM 客户端意外关闭时的情况的代码,在这种情况下,我应该在 COM 服务器代码中关闭 COM 服务器。

我该怎么做?

UPD:我遇到了 COM 服务器挂起或更正确的情况,我无法从 COM 客户端连接到 COM 服务器,但包含 COM 服务器的应用程序仍处于活动状态,因此我认为 COM 服务器可以检测到所有旧 COM 客户端已断开/关闭/崩溃,应用程序将重新启动,因为没有附加新客户端。

我在 COM 客户端的单独线程中编写了以下代码

while(not we are closing)
{
   unknown->QueryInterface(IComServer, &server);

   if (server)
     return;
}

所以 COM 客户端可以等到服务器真正准备好工作

UPD2:刚刚测试:12 分钟后我的 COM 服务器关闭

【问题讨论】:

  • 您认为这样做有什么好处?
  • @David Heffernan:显然他不希望 COM 服务器进程无限期地挂起。

标签: windows com


【解决方案1】:

COM 定期 ping 客户端以查看它们是否还活着,并从死客户端运行接口。所以你的服务器最终会发现的。

【讨论】:

  • 我自己从来没有听说过也没有见过。两个小时前我启动了一个进程外服务器并杀死了客户端。它仍在运行。很高兴看到这方面的参考资料,谷歌搜索不好。
  • 客户端断开连接后 6 或 12 分钟后应该会出现故障,fwiw。它确实发生了。您是否在服务器对象的 Release() 方法上设置了断点以确认它没有被调用?可能还有另一个参考可以使您的服务器保持活动状态。
  • @Larry,我通过获取对 msword 的 _Application 接口的单一引用来保持简单。它没有发生。
  • msword 可能有来自 GUI 的额外引用,因此它不会在没有用户操作的情况下自动关闭。当客户端死机时,普通 COM 服务器会收到 IUnknown::Release 调用。
  • 没有 gui。如果这是真的,那么它肯定会记录在某处吗?这是特定于 DCOM 的吗?
【解决方案2】:

只要您有两个或进程互操作,就会存在这个漏洞。其中一个死了,另一个继续运行,不知道死进程再也不会有另一个请求了。在进程外 COM 服务器的情况下,没有人会调用 IUnknown::Release() 来销毁对象。 COM 没有针对该问题的内置修复程序。进程内服务器没有这个问题,崩溃的进程也将服务器取出。这也是一个问题,没有很好的清理,但更容易处理。

让服务器从中恢复是您必须自己添加的内容。例如,您可以让客户端传递其进程 ID,以便服务器可以获取进程句柄并使用 WaitForMultipleHandles() 检测客户端何时崩溃。假设它们都存在于机器上,那肯定不是 COM 要求,也不是服务器可以发现的。

【讨论】:

  • 我喜欢你的想法 - Com Client 接收 Com Server 的句柄,使用 WaitForMultipleHandles 创建线程,当 Com Server 失败时,它将指向服务器的指针设为 null。所以客户端可能永远不会调用挂起的服务器
【解决方案3】:

COM 将在客户端死亡后的某个时间在 out-proc 服务器中释放服务器端对象,但前提是该对象中没有执行调用。这是关键——COM 不可能停止正在进行的呼叫。因此解决方案是使方法运行时间短,并保证在一些合理的短时间(如几秒钟)内完成。这样,一旦客户端死亡,就没有新的调用来自它,并且在一段时间后正在进行的调用自然结束,然后在超时后 COM 释放服务器中的对象,服务器可以自然停止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2010-09-15
    • 2017-09-09
    • 1970-01-01
    • 2011-11-10
    • 2011-09-18
    • 2010-11-06
    相关资源
    最近更新 更多