こんにちは、いくつかの簡単な検索トリックを実行する Outlook com アドインがあります。組み立ての途中ですが、メモリ不足の問題が発生しています。プロセスは非常に単純で、基本的に Outlook フォルダーをループして、各 mailItem が一致するかどうかをチェックします。ループが変数を再初期化すると、ガベージコレクターが追いつくと予想されるたびに変数が再初期化されますが、メモリを監視すると、システムがメモリ不足になり、未処理の例外が発生するまで、メモリは約 10m/秒失われます。
これはコードの一部です
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 個の mailItem ごとに手動 GC が実行されますが、これはまったく違いがありませんでした。
何らかの理由で、アイテムをループするだけで大量のメモリが必要になり、GC はアイテムを解放しません。
Comアドイン用のVSTOではなく、netofficeを使用していることにも注意してください。