【问题标题】:Outlook VSTO Add-in: Removing a lot of recipients is too slow and not always workOutlook VSTO 加载项:删除大量收件人太慢且并不总是有效
【发布时间】:2022-08-09 02:48:54
【问题描述】:

我有一个 VSTO Outlook 加载项。在撰写窗口中,我有一个按钮。单击此按钮时,将删除满足条件的收件人。需要删除的收件人存储在一个列表中,即 List<Outlook.Recipient>。我迭代这个列表并删除每个收件人。

foreach (Outlook.Recipient recipient in this.RecipientsList)
{
    this.MyMailItem?.Recipients?.Remove(recipient.Index);
}

// clear all the recipients
this.RecipientsList.Clear();

我已经注意到,需要删除的收件人越多,速度就越慢,而且并非总是删除列表中包含的所有收件人,有时甚至有时不会。这里有两件事:

  • 如何优化删除收件人的速度?
  • 为什么有时列表中包含的所有收件人都没有被删除?它是随机的,有时是,有时不是。

请注意,this.MyMailItem 的类型为 Outlook.MailItem,而 this.MyMailItem.Recipients 的类型为 Outlook.Recipients。

删除函数需要一个整数作为参数,这就是它的定义,见这里。

    标签: outlook vsto outlook-addin office-interop office-addins


    【解决方案1】:

    将 Outlook COM 对象保留在集合中并不是一个好主意。相反,您可以保留它们的索引等。

    在以下循环中:

    foreach (Outlook.Recipient recipient in this.RecipientsList)
    {
        this.MyMailItem?.Recipients?.Remove(recipient.Index);
    }
    

    recipient 对象被忽略!

    您可以使用以下内容:

    foreach (Outlook.Recipient recipient in this.RecipientsList)
    {
        recipient.Delete();
    }
    

    Recipient.Delete 方法从集合中删除一个对象。

    经验法则是立即释放底层 COM 对象。在这种情况下,您可以确定对象会及时释放。例如,在每次循环中的代码中,您都会获得 Recipients 集合,该集合会增加引用计数器:

    this.MyMailItem?.Recipients
    

    我建议保留集合并仅处理循环中的特定项目:

    Outlook.Recipients recipients = this.MyMailItem?.Recipients;
    // in the loop you can call the Remove method
    recipients.Remove(recipient.Index);
    

    您也可以尝试在循环中获取特定的收件人实例并将其删除。之后,您还需要释放一个底层 COM 对象:

    Outlook.Recipient recipient = null;
    Outlook.Recipients recipients = this.MyMailItem?.Recipients;
    for(int i = 1; i<recipients.Count;i++)
    {
        recipient = this.RecipientsList.Item(i);
        recipient.Delete();
        Marshal.ReleaseComObject(recipient);
        recipient = null;
    }
    

    【讨论】:

    • 在您的最后一段代码中,您执行了 recipient = this.RecipientsList[i] 但这可能会引发和超出范围异常,因为 RecipientsList 始终是:RecipientsList.Count <= recipients。我的意思是,RecipientsLIst 可以包含与收件人数量相同或更少的收件人。我正在尝试从包含在 this.MyMailItem.Recipients 集合中的 RecipientsList 中删除所有收件人。
    • 那是一个原始草图,我没有在 IDE 中检查它。您可以尝试在 C# 中使用 Item 方法而不是索引器。
    • 好的,谢谢,我怎样才能发布收件人列表 List<Outlook.Recipient> ?我是否需要循环整个列表并为每个项目执行 Marshal.ReleaseComObject(recipient) 然后设置为 null ?
    • 是的,但这取决于您检索这些实例的位置。
    • 你释放底层的 COM 对象吗?您当前的代码是什么?
    猜你喜欢
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 2023-03-17
    • 2021-09-02
    • 1970-01-01
    • 2017-11-04
    • 2018-03-25
    • 2020-09-18
    相关资源
    最近更新 更多