C#VSTO Outlook加载项:不释放MailItem对象可能有什么影响

问题描述 投票:1回答:2

与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

] >>
c# outlook vsto outlook-addin office-addins
2个回答
0
投票
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); }

0
投票
TL; DR:不要调用Marshal.ReleaseComObject,因为它没有用处,更重要的是,它是
dangerous
© www.soinside.com 2019 - 2024. All rights reserved.