【发布时间】:2015-05-20 17:20:57
【问题描述】:
您好,我有一个 Outlook com 插件,它正在为我做一些简单的搜索技巧。我正在将它放在一起,但我遇到了内存不足的问题。这个过程非常简单,基本上循环通过一个outlook文件夹检查每个mailItem是否匹配。给定循环每次我希望垃圾收集器跟上时都会重新初始化变量,但是当我观察内存时,它会损失约 10 米/秒,直到系统内存不足并且我得到未处理的异常。
这是代码的一部分
private void FindInFolder(Outlook.MAPIFolder FolderToSearch)
{
Outlook.MailItem mailItem;
Outlook.MAPIFolder ParentFolder;
int counter = 0;
StatusBar.Text = "Searching in Folder " + FolderToSearch.FolderPath + "/" + FolderToSearch.Name;
StatusBar.Update();
this.Update();
foreach (COMObject item in FolderToSearch.Items)
{
counter++;
if (counter % 100 == 0)
{
StatusBar.Text = FolderToSearch.FolderPath + "/" + FolderToSearch.Name + " item " + counter + " of " + FolderToSearch.Items.Count;
StatusBar.Update();
if (counter % 1000 == 0)
{
GC.Collect();
}
}
if (item is Outlook.MailItem)
{
mailItem = item as Outlook.MailItem;
if (IsMatch(mailItem))
{
if (mailItem.Parent is Outlook.MAPIFolder)
{
ParentFolder = mailItem.Parent as Outlook.MAPIFolder;
ResultGrd.Rows.Add(mailItem.EntryID, ParentFolder.FolderPath, mailItem.SenderName, mailItem.Subject, mailItem.SentOn);
}
}
}
mailItem = null;
}
}
哪些调用
private Boolean IsMatch(Outlook.MailItem inItem)
{
Boolean subBool = false;
Boolean NameBool = false;
try
{
if (null != inItem)
{
if (SubjectTxt.Text != "")
{
if (inItem.Subject.Contains(SubjectTxt.Text))
{
subBool = true;
}
}
else
{
subBool = true;
}
if (NameTxt.Text != "")
{
if (inItem.Sender != null)
{
if (inItem.Sender.Name.Contains(NameTxt.Text))
{
NameBool = true;
}
}
}
else
{
NameBool = true;
}
return subBool && NameBool;
}
}
catch (System.Runtime.InteropServices.COMException ce)
{
if (ce.ErrorCode == -2147467259)
{
//DO nothing just move to the next one
}
else
{
MessageBox.Show("Crash in IsMatch error code = " + ce.ErrorCode + " " + ce.InnerException);
}
}
return false;
}
请原谅底部的所有错误捕获部分和 GC.collect 它们是我尝试找出问题并释放内存的一些尝试。
还要注意 FindInFolder 由一个新线程调用,因此我可以在它继续搜索的同时与结果进行交互。
到目前为止我所尝试的:
将变量设置为函数而非类的局部变量,以便 G 可以检索,但是 'item' 中最常用的变量,因为它是 foreach 的一部分,因此必须以这种方式声明。
每 1000 个邮件项执行一次手动 GC,这根本没有区别。
由于某种原因,它需要大量内存,只是循环遍历项目,而 GC 永远不会释放它们。
另请注意,我使用的是 netoffice 而不是 VSTO 用于 Com 插件。
【问题讨论】:
-
我的记忆可能在这里模糊不清,但在互操作命名空间中调用了一个方法,您必须显式调用该方法才能释放 COM 对象。至少 Office 互操作就是这种情况。
-
我会做一些与上述评论相关的谷歌搜索,谢谢
-
您是否尝试过使用
System.Runtime.InteropServices.ReleaseComObject强制释放 com 对象,因为您已经完成了它们? -
不,我没有,它对每个变量都做了吗?我会谷歌一个例子谢谢
-
@MattHouser 可能正在阅读此页面edndoc.esri.com/arcobjects/9.2/NET/…
标签: c# garbage-collection outlook-addin netoffice