3

当有人使用任务管理器结束实例化 COM 对象的 .NET 进程时,AFAIK 无法调用Marshal.FinalReleaseComObject,或事件处理块。try {} finally {}using {}

下次我启动应用程序时,COM 对象处于不可用状态,我需要重新启动机器以使其再次工作。

Marshal.BindToMoniker用来实例化对象。

我做错了什么,我错过了什么吗?


我尝试了 Saeed 的建议,但没有奏效

private const int WM_CLOSE = 0x0010;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_CLOSE)
    {
        logger.Info("WM_CLOSE");
        Marshal.FinalReleaseComObject(comObject);
    }

    base.WndProc(ref m);
}
4

2 回答 2

1

你可能不需要。当垃圾收集器开始释放内存时,它会检查对象是否具有尚未调用的 Dispose() 方法。如果尚未调用 Dispose() 方法,它将调用它。

我在控制台应用程序中对此进行了测试,并且在我的 Dispose 功能中发出了 3 次扬声器哔声。退出应用程序后,没有在对象上调用 Dispose,大约需要 30 秒才能听到 3 声哔哔声。时间是不确定的。

当然,对象必须已正确编码。

您是否尝试在关闭后立即运行应用程序?为什么不等几分钟,看看它是否有效?

编辑:我假设您的 Dispose 函数中有 Marshal.FinalReleaseComObject 。

于 2012-08-21T01:24:49.097 回答
1

任务管理器正在使用本机等价物Process.Kill(或者可能更强大)。请注意文档中的此叙述:

Kill强制终止进程,而CloseMainWindow仅请求终止。

...

调用CloseMainWindow发送关闭主窗口的请求,在格式良好的应用程序中...

和,

如果您调用Kill. Kill导致进程异常终止,仅在必要时使用。

简而言之,您实际上无法从程序代码内部做任何事情来防止这种情况发生 - 插头已被拔掉。不会发送任何窗口消息。

于 2012-08-21T14:23:21.880 回答