【问题标题】:Is there any harm in killing a COM server without releasing com objects in .net?杀死 COM 服务器而不释放 .net 中的 com 对象有什么害处吗?
【发布时间】:2011-03-10 04:50:28
【问题描述】:

伙计们 - 我在 .net 中创建了许多 COM 服务器(我正在启动许多 EXE),通过 COM -interop 与 COM 对话,在服务器中使用许多 COM 对象等。如果我终止进程,是否存在有什么害处吗?不释放我通过 Marshal.FinalReleaseComObject() 使用的所有 COM 对象有什么不好的吗?随着时间的推移,我会出现内存泄漏吗?

【问题讨论】:

    标签: .net com com-interop com-server


    【解决方案1】:

    我假设您说的是进程外 COM 服务器,尽管它们远不如进程内服务器常见。杀死客户端应用程序是不好的,服务器永远不会获得释放调用,客户端分配的任何对象的资源将一直使用,直到 EXE 终止。杀死服务器应用程序将使客户端应用程序失败并出现 RPC 错误,不会泄露任何内容。

    不使用 Marshal.FinalReleaseComObject() 并没有什么不好,COM 对象引用计数由 RCW(运行时可调用包装器)管理。它与 .NET 编程中的任何其他对象一样是托管对象,垃圾收集器负责处理它。当终结器运行时,引用计数递减。什么时候发生是不可预测的。

    使用 Final/ReleaseComObject() 可以使其可预测,但您必须在您创建的 每个 对象上调用它。这可能很困难,例如,当您使用索引器时创建一个并不总是很明显。这也是危险的,错误的调用时间或没有正确跟踪对对象的所有引用会导致臭名昭著的“无法使用已与其底层 RCW 分离的 COM 对象”异常。一个好的战争故事是available here

    【讨论】:

    • 嗨,汉斯。正确,我说的是进程外 COM 服务器。同意,杀死客户端(我们的意思是 .net 应用程序对吗?)是不好的。当您说杀死服务器应用程序(COM 应用程序)会使客户端应用程序因 RPC 错误而失败时,这仅适用于尝试调用服务器时,对吗?如果服务器进程被杀死,并且不再对服务器进行调用,那么 .net 将垃圾收集任何资源并且世界是一个美好的地方?
    • 并非如此。在客户端创建 one 对象就足以导致 RPC 错误。总会有一个(否则不可见的)调用来释放它。 GC 做到了。只有在客户端根本不使用服务器时才杀死它是安全的。这是显而易见的。
    • 抱歉...我在关注您的最后一条评论时遇到了问题。也许我们可以举一个 Excel 自动化的具体例子。要启动 Excel exe,必须实例化 Excel 应用程序对象 (var app = new Application())。然后我们可以做各种花哨的事情,比如 Application.Workbooks[0].Worksheets[0].Range["A1"] = "123"。所以 .net 是客户端,Excel 是服务器。如果我在 taskmanager 中杀死 Excel.exe 并且不再调用应用程序,那么就不可能出现 RPC 错误并且 GC 会清理混乱?
    • GC 通过释放 Application 对象和您的代码使用的任何其他 RCW 来清理混乱。 Release() 调用会出现 RPC 错误,但是当我测试它时,CLR 似乎忽略了它。有点道理,没有必要在发布调用中抱怨“服务器已消失”错误。
    猜你喜欢
    • 2015-09-25
    • 2012-09-17
    • 2010-11-29
    • 2015-07-09
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2012-03-05
    相关资源
    最近更新 更多