Outlook 共有メールボックス内の多数のフォルダーを監視する WPF アプリケーションに取り組んでいます。ItemAdd および ItemRemove イベント ハンドラーを Folder.Items オブジェクトに接続しました。
すべてが数分間うまく機能します。しかし、時間が経つにつれて、イベント処理は「だめ」になるようです。一部のフォルダは引き続き追加と削除を認識し、他のフォルダは削除のみを表示しますが、他のフォルダはアクティビティを認識しません. 私には、イベント ハンドラーがガベージ コレクションされているように見えますが、私の Items オブジェクトは、それが置かれているクラスでグローバル変数として宣言されているため、それらがどのように GC されるのかわかりません。
Outlook Folder.Items イベントで注意すべき落とし穴はありますか? 同様のプロセスで動作する以前のより単純なアプリケーションがあり、長期間にわたって正常に動作します。Item イベント処理に関する限り、私の古いアプリとこの新しいアプリの間に本質的な違いはありません。私はこれを引き起こしているものについて本当に途方に暮れています。
以下は関連するコードです。これにいくつかのコンテキストをもたらすために、私がやっていることは、Outlook 共有メールボックスの各フォルダーに対して、そのフォルダーの内容 (MailItems) を表す "TicketView" UserControl が作成されることです。この TicketView は、0 から数十個の MailItems を含む単純な ListBox であり、余分なものはありません。
public partial class TicketView : UserControl
{
private Folder _thisFolder = null;
private TicketCollection _thisTicketColl = null;
private Items _thisItems = null;
public TicketView(Folder folder)
{
InitializeComponent();
_thisTicketColl = this.FindResource("TicketCollection") as TicketCollection;
_thisFolder = folder;
_thisItems = folder.Items;
SetFolderEvents();
Refresh();
}
private void SetFolderEvents()
{
_thisItems.ItemAdd += new ItemsEvents_ItemAddEventHandler(delegate
{
Refresh();
});
_thisItems.ItemRemove += new ItemsEvents_ItemRemoveEventHandler(delegate
{
Refresh();
});
}
public void Refresh()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(delegate(object sender, DoWorkEventArgs e)
{
string[] fields = new string[] { "Subject", "SenderName", "SentOn", "EntryID" };
var olTable = TicketMonitorStatics.GetOutlookTable(_thisFolder, fields, filter);
olTable.Sort("SentOn", true);
var refreshedList = new List<Ticket>();
while (!olTable.EndOfTable)
{
var olRow = olTable.GetNextRow();
refreshedList.Add(new Ticket
{
Subject = olRow["Subject"],
Sender = olRow["SenderName"],
SentOn = olRow["SentOn"],
EntryID = olRow["EntryID"]
});
};
e.Result = refreshedList;
});
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object sender, RunWorkerCompletedEventArgs e)
{
var refreshedList = e.Result as List<Ticket>;
UpdateTicketList(refreshedList);
worker.Dispose();
});
worker.RunWorkerAsync();
}
private void UpdateTicketList(List<Ticket> newList)
{
_thisTicketColl.Clear();
foreach (Ticket t in newList)
{
_thisTicketColl.Add(t);
}
}
}
}