问题:
我必须通过来自C#.NET应用程序的COM interop调用应用程序。我已经编写了一个包装类来处理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中,我可以在svchost.exe
下使用werfault.exe
进程查看应用程序的进程,即使我在捕获COMException
后手动调用垃圾收集器。
catch(COMException)
{
app.Dispose();
app = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
如何以正确退出应用程序并关闭进程的方式正确处理COM对象,即使该COM应用程序已崩溃?我考虑过确定所述应用程序的进程ID并使用Process.Kill()
,但这对我来说似乎有点难看。那么什么是终止和释放崩溃应用程序资源的适当方法呢?
答案 0 :(得分:2)
如果这是外部COM服务器,则无法从客户端执行任何操作。
在你身边,除了你已经做的事情,你可以做任何其他事情。处理COM对象,你就完成了。如果COM应用程序仍然存在,则会有一些错误处理程序导致应用程序不关闭。也许它显示错误信息。
但我想知道,你看到了一个SVCHOST进程。这是一项服务吗?如果是这样,SCM应该管理失败。 COM通常在SVCHOST.EXE中托管外部服务器。
因此,您可能没有提供有关所使用的外部流程类型的足够信息。
BTW:调用GC.Collect永远不会明智......;)