C# VSTO Outlook 插件:不释放 MailItem 对象的可能影响是什么

Kin*_*njo 2 c# outlook vsto office-addins outlook-addin

Marshal.ReleaseComObject在 Outlook 中与 MailItems 交互时使用的重要性是什么?

我参考了在https://docs.microsoft.com/en-us/visualstudio/vsto/walkthrough-creating-your-first-vsto-add-in-for-outlook?view创建 C# VSTO Outlook 插件的演练 =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";
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

该示例结束时没有提及使用 释放邮件项目对象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 会导致问题的特定用例?

谢谢

Dmi*_*nko 5

如果您不调用Marshal.ReleaseComObject,该对象将作为垃圾收集器稍后破坏的某个点被释放。通常,这不是问题 - 在处理大量项目时,您通常需要小心,不要随意发布。在这种特殊情况下,Marshal.ReleaseComObject除非您想确保发布该项目,以防它在外部更新,并且您不希望 Outlook 对象模型以过时的对象结束,否则您将没有问题。

请注意,仅Marshal.ReleaseComObjectmailItem变量上是不够的 - 您需要小心隐式变量,例如,当您使用多点表示法时。一些 .Net 运算符也以隐式变量结束,并且as是其中之一(以及is):

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 唉……是的,GC会释放这些对象。最终...你无法控制何时。并且(在在线 Exchange 的情况下)一旦您打开超过 250 个 RPC 通道,您就会遇到异常。在GC有机会为你做任何事情之前。如果需要避免这种情况,则需要使用 Marshal.ReleaseComObject。 (2认同)