我在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循环中调用的,该循环遍历文件夹,谢谢。
发布于 2021-08-03 04:46:46
首先,循环遍历文件夹中的所有项目不是一个好主意。你真的需要这么做吗?
您一直在循环中检索Item集合(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);发布于 2021-08-03 10:19:31
正确地释放底层COM对象对您的目标是不够的。您需要使用Find/FindNext或Items类的Restrict方法来查找带有附件的项,而不是迭代文件夹中的所有项,只有这样,您才能只遍历带有附件的所有项。查询可以使用SQL表示法(VBA):
query ="@SQL=" & chr(34) & "urn:schemas:httpmail:hasattachment" & chr(34) & "=1"请参阅以下文章中有关这些方法的更多信息:
此外,您可能会发现Application类的AdvancedSearch方法很有用。在Outlook中使用AdvancedSearch方法的主要好处是:
AdvancedSearch方法在后台自动运行它。Restrict和Find/FindNext方法可以应用于特定的Items集合(请参阅Outlook中Folder类的Items属性)。IsInstantSearchEnabled类的Store属性),则可以使用即时搜索关键字。Stop类的Search方法在任何时候停止搜索过程。有关详细信息,请参阅以编程方式在Outlook中进行高级搜索: C#、VB.NET。
https://stackoverflow.com/questions/68630201
复制相似问题