何时正确释放 Outlook COM 对象?

When to correctly release Outlook COM-objects?

我知道这里有人问过类似的问题,但我觉得我没有理解正确。

例如我有以下代码:

Microsoft.Office.Interop.Outlook.Explorer expl = myOutlooApplication.ActiveExplorer();
if (expl.Selection.Count > 0)
{
    object selObject = expl.Selection[1];
    if (selObject is Microsoft.Office.Interop.Outlook.MailItem)
    {
        mailItem = (selObject as Microsoft.Office.Interop.Outlook.MailItem);
        this.myUserControl.MailItem = mailItem;
    }
}

如您所见,MailItem 被传递到 myUserControl 的 属性。 MyUserControl 稍后需要访问此 属性 以从 MailItem 中提取一些信息。

我应该 Marshal.ReleaseComObject() 在将 MailItem 传递给 myUserControl 之后减少 RCW 的引用计数器还是这太早了?

编辑: 我的问题是,将从文件系统打开一个 .msg 文件。关闭检查器后,用户尝试再次打开该文件,但它已被锁定,我确信 COM 对象未正确释放是造成这种情况的原因。

除非您有与您的 COM 对象相关联的内存泄漏记录,否则不要开始乱用 Marshal COM 方法。 RCW 负责将 .NET 的垃圾收集世界转换为 COM 的引用计数世界,并且通常做得很好。

可能考虑在你确定没有托管引用的情况下用Marshal.FinalReleaseComObject强制退出对象将被访问 and COM 对象消耗大量资源。您可能需要考虑使用 IDisposable 包装器将 that 翻译成 .NET 术语。您肯定不在您显示的代码中的那个位置 - 您知道您刚刚将对 RCW 的托管引用传递给 myUserControl 并且您可能希望它访问该引用。

.NET 对 RCW 的引用不是 COM 计数的引用类型。

is 运算符创建了一个隐式变量,所以你在那里有一个泄漏(GC 当然会稍后释放它)。
将您的代码更改为以下内容。它不会帮助您处理 MSG 文件,因为它永远不会通过资源管理器访问。 this.myUserControl.MailItem当然也必须在完成后立即发布。

    object selObject = expl.Selection[1];
    MailItem mailItem =  selObject as MailItem;
    if (mailItem != null)
    {
        this.myUserControl.MailItem = mailItem;
    }
    Marshal.ReleaseComObject(mailItem);