如果 COM 应用程序崩溃,如何正确处理 COM 对象?

How to properly Dispose a COM Object if the COM application crashed?

问题:

我必须通过 COM 互操作从 C# .NET 应用程序调用应用程序。我写了一个包装器 class 来处理 COM 的东西,所有这些东西都很好用。

public sealed class ComWrapper : IDisposable
{
    private Application comApplication = new Application(); // Referenced COM assembly.
    private bool disposed;

    // Several methods to interact with the com application.

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
         if(disposed)
             return;

         try
         {
             if(comApplication != null && Marshal.IsComObject(comApplication));
                 Marshal.ReleaseComObject(comApplication);
         }
         finally
         {
             comApplication = null;
         }

         disposed = true;
    }
}

我可以调用该应用程序,使用它的方法,只要 COM 应用程序运行正常,一切正常。

但是,如果应用程序崩溃(有时会在数据库连接丢失时发生),可执行文件将保持加载状态。在 Process Explorer 中,即使我在捕获 COMException.

后手动调用垃圾收集器,我也可以在 svchost.exe 下看到应用程序的进程和 werfault.exe 进程
catch(COMException)
{
    app.Dispose();
    app = null;
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

如何正确处理 COM 对象,即使 COM 应用程序崩溃,它也能正确退出应用程序并关闭进程?我考虑过确定所述应用程序的进程 ID 并使用 Process.Kill() 但这对我来说似乎有点难看。那么终止和释放崩溃应用程序资源的适当方法是什么?

如果这是一个外部 COM 服务器,您无法从客户端执行任何操作。

在你这边,除了你已经在做的事情,你什么也做不了。处理 COM 对象,您就完成了。如果 COM 应用程序仍然存在,则有一些错误处理程序会导致应用程序无法关闭。可能显示错误消息。

但我想知道,您是否看到了一个 SVCHOST 进程。这是服务吗?如果是这样,SCM 应该管理故障。 COM 通常在 SVCHOST.EXE.

中托管外部服务器

所以您可能没有提供足够的关于所使用的外部进程类型的信息。

顺便说一句:调用 GC.Collect 从来都不是明智的... ;)