何时正确释放 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);
我知道这里有人问过类似的问题,但我觉得我没有理解正确。
例如我有以下代码:
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);