与Outlook中的MailItem交互时使用Marshal.ReleaseComObject的重要性是什么?
我指的是在以下位置创建C#VSTO Outlook加载项的演练https://docs.microsoft.com/en-us/visualstudio/vsto/walkthrough-creating-your-first-vsto-add-in-for-outlook?view=vs-2019
他们有修改现有选定邮件项目的主题和正文的示例。
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
Outlook.MailItem mailItem = Inspector.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
if (mailItem.EntryID == null)
{
mailItem.Subject = "This text was added by using code";
mailItem.Body = "This text was added by using code";
}
}
}
该示例结束时未提及使用Marshal.ReleaseComObject释放邮件项目对象的情况>>
但是在https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.releasecomobject?view=netframework-4.8的.Net API参考中,他们提到:
您应该使用此方法来释放底层的COM对象,该对象及时包含对资源的引用,或者在必须按特定顺序释放对象时。
因此,如果我们未能在要引用的MailItem上使用Marshal.ReleaseComObject,则会产生一些后果?
是否存在不使用Marshal.ReleaseComObject的特定用例会导致问题?
谢谢
与Outlook中的MailItems交互时使用Marshal.ReleaseComObject的重要性是什么?我指的是在https://docs.microsoft.com/zh-cn]上创建C#VSTO Outlook插件的演练。
如果不调用Marshal.ReleaseComObject
,则对象将作为垃圾回收器稍后释放的点被释放。通常,这不是问题-在处理大量项目时,您通常需要小心,不要使发行版具有偶然性。在这种特殊情况下,如果没有Marshal.ReleaseComObject
,就可以了,除非您要确保该项目已发布,以防它在外部更新,并且您不希望Outlook对象模型以陈旧的对象结尾。
请注意
Marshal.ReleaseComObject
变量上的
mailItem
是不够的-您需要注意隐式变量,例如当您使用多点符号时。一些.Net运算符也以隐式变量结尾,
as
是其中之一:
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
object item = Inspector.CurrentItem;
Outlook.MailItem mailItem = item as Outlook.MailItem;
if (mailItem != null)
{
if (mailItem.EntryID == null)
{
mailItem.Subject = "This text was added by using code";
mailItem.Body = "This text was added by using code";
}
Marshal.ReleaseComObject(mailItem);
}
Marshal.ReleaseComObject(item);
}
TL; DR:不要调用Marshal.ReleaseComObject
,因为它没有用处,更重要的是,它是
dangerous。请参阅下面的引文。
与Outlook中的MailItems交互时使用Marshal.ReleaseComObject的重要性是什么?
不需要,您不需要。因此,如果我们在引用的MailItem上无法使用Marshal.ReleaseComObject,显然会产生一些后果?
不正确。
是否存在不使用Marshal.ReleaseComObject的特定用例会导致问题?
Not称呼它是正确的情况。MSDN article的
备注
部分有些混乱,并且误导。行:您应该使用此方法来释放底层的COM对象,该对象及时包含对资源的引用,或者在必须按特定顺序释放对象时。
...应该真的出现在[[之后
更重要的一点:因此,请使用ReleaseComObject
仅在绝对必要时使用
。如果要调用此方法以确保在确定的时间释放COM组件,请考虑改用FinalReleaseComObject方法...和:此方法使您可以强制释放RCW参考计数,以便它在您需要的时候准确发生。但是,对ReleaseComObject的不正确使用可能会导致您的应用程序失败
,或者可能导致访问冲突
实际上,在正常使用中,您根本不需要调用此方法。最后,因为您要为Outlook制作外接程序,所以也几乎不需要释放COM对象,因为您访问的任何对象都是由Outlook本身创建的,并且您的代码在与Outlook相同的进程空间中运行。 Outlook已经知道这些对象,并且知道何时摆脱它们。好像您正在启动一个外部进程,例如说MS Word,并担心通过COM进行通信后,Word的孤立实例会引起关注。
汉斯·帕桑特说:
不需要自己存储这些对象引用并显式调用Marshal.ReleaseComObject(),CLR会为您完成... more
另请参见
(尽管提到了Excel,但链接仍然相关,因为Outlook和Excel都使用COM)
[Clean up Excel Interop Objects with IDisposable
] >>
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
object item = Inspector.CurrentItem;
Outlook.MailItem mailItem = item as Outlook.MailItem;
if (mailItem != null)
{
if (mailItem.EntryID == null)
{
mailItem.Subject = "This text was added by using code";
mailItem.Body = "This text was added by using code";
}
Marshal.ReleaseComObject(mailItem);
}
Marshal.ReleaseComObject(item);
}
TL; DR:不要调用Marshal.ReleaseComObject
,因为它没有用处,更重要的是,它是
dangerous