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



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

代码是:

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循环中调用的,该循环遍历文件夹,提前感谢

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

query ="@SQL=" & chr(34) & "urn:schemas:httpmail:hasattachment" & chr(34) & "=1"

在以下文章中阅读更多关于这些方法的信息:

  • 如何:使用Find和FindNext方法从文件夹中检索Outlook邮件项目(c#, VB.NET)
  • 如何:使用Restrict方法从文件夹
  • 中检索Outlook邮件项目

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

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

参见Outlook编程高级搜索:c#, VB。. NET获取更多信息。

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

继续在循环中检索Items集合(folder.Items[k])。在进入循环之前缓存Items:

Items items = folder.Items;
for (int k = 1; k <= items.Count; k++)
{
object item = items[k];
...
}
Marshal.ReleaseComObject(items);

您正在泄漏引用(它们稍后将由GC释放),但是由于您正在使用FinalReleaseComObject…

object item = items[k];
MailItem mailItem = item as MailItem;
if (mailItem != null)
{
...
Marshal.ReleaseComObject(mailItem);
}
Marshal.ReleaseComObject(item);

最新更新