首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从outlook获取电子邮件时VSTO C#中的For循环的性能问题

从outlook获取电子邮件时VSTO C#中的For循环的性能问题
EN

Stack Overflow用户
提问于 2021-08-03 03:58:39
回答 2查看 177关注 0票数 0

我在outlook收件箱文件夹(C# VSTO添加在Outlook中)中的电子邮件循环有问题。我使用了foreach循环,但是它消耗了大量内存,然后导致异常:系统/内存资源不足。所以,我现在使用的是for循环,它不会导致这个错误,但是对于其中一个文件夹,它非常慢,每秒读取的电子邮件少于5-8封。这个文件夹包含10万多封电子邮件。对于所有其他文件夹,速度在30-35封电子邮件之间。

守则是:

代码语言:javascript
复制
Static void IterateMessages(Outlook.Folder folder){

        int tempCount = folder.Items.Count;
        if (folder.Items != null)
        {
            Object item;
            for (int k = 1; k <= tempCount; k++)
            {
                item = folder.Items[k];
                if (item is Outlook.MailItem)
                {
                    emailCount++;
                    try
                    {
                        SaveAttachment(item);
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine("An error occurred Iterate Message: '{0}'", e);
                    }
                }
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(item);
                item = null;
            }
            tempCount = 0;
        }
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(folder);
    }

如果有人能帮忙解决这个问题,那就太好了。在使用foreach循环时,速度接近。每秒40-45封电子邮件。另外,这个方法也是从另一个for循环中调用的,该循环遍历文件夹,谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-03 04:46:46

首先,循环遍历文件夹中的所有项目不是一个好主意。你真的需要这么做吗?

您一直在循环中检索Item集合(folder.Items[k])。进入循环之前缓存Items

代码语言:javascript
复制
Items items = folder.Items;
for (int k = 1; k <= items.Count; k++)
{
  object item = items[k];
  ...
}
Marshal.ReleaseComObject(items);

您正在泄漏引用(当然稍后会由GC发布),但是由于您使用的是FinalReleaseComObject.

代码语言:javascript
复制
object item = items[k];
MailItem mailItem = item as MailItem;
if (mailItem != null)
{
  ...
  Marshal.ReleaseComObject(mailItem);
}
Marshal.ReleaseComObject(item);
票数 0
EN

Stack Overflow用户

发布于 2021-08-03 10:19:31

正确地释放底层COM对象对您的目标是不够的。您需要使用Find/FindNextItems类的Restrict方法来查找带有附件的项,而不是迭代文件夹中的所有项,只有这样,您才能只遍历带有附件的所有项。查询可以使用SQL表示法(VBA):

代码语言:javascript
复制
query ="@SQL=" & chr(34) & "urn:schemas:httpmail:hasattachment" & chr(34) & "=1"

请参阅以下文章中有关这些方法的更多信息:

此外,您可能会发现Application类的AdvancedSearch方法很有用。在Outlook中使用AdvancedSearch方法的主要好处是:

  • 搜索在另一个线程中执行。您不需要手动运行另一个线程,因为AdvancedSearch方法在后台自动运行它。
  • 在任何位置搜索任何项目类型的可能性:邮件、约会、日历、便条等,即超出某个文件夹的范围。RestrictFind/FindNext方法可以应用于特定的Items集合(请参阅Outlook中Folder类的Items属性)。
  • 完全支持DASL查询(自定义属性也可用于搜索)。您可以在MSDN中的过滤文章中阅读更多有关这方面的内容。为了提高搜索性能,如果对存储启用了即时搜索(请参阅IsInstantSearchEnabled类的Store属性),则可以使用即时搜索关键字。
  • 您可以使用Stop类的Search方法在任何时候停止搜索过程。

有关详细信息,请参阅以编程方式在Outlook中进行高级搜索: C#、VB.NET

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68630201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档