我正在开发一个 WPF 应用程序来监视 Outlook 共享邮箱中的多个文件夹。我已将 ItemAdd 和 ItemRemove 事件处理程序连接到 Folder.Items 对象。
一切都很好用了几分钟。但随着时间的推移,事件处理似乎变得“噗嗤”一声。一些文件夹仍然可以识别添加和删除,其他文件夹只会看到删除,而其他文件夹则对任何活动视而不见。对我来说,似乎事件处理程序正在被垃圾收集,但我的 Items 对象被声明为它所在的类中的全局变量,所以我看不出它们是如何被 GC 淘汰的。
Outlook Folder.Items 事件有什么我应该注意的陷阱吗?我有一个以前的更简单的应用程序,它通过类似的过程工作,可以在很长一段时间内正常工作。就项目事件处理而言,我的旧应用程序和这个新应用程序之间没有本质区别。我真的不知道是什么原因造成的。
下面是相关代码。为了带来一些上下文,我正在做的是,对于 Outlook 共享邮箱中的每个文件夹,都会创建一个“TicketView”用户控件,它代表该文件夹的内容(MailItems)。这个 TicketView 是一个简单的 ListBox,它可能包含 0 到几十个 MailItems - 没有太多。
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);
}
}
}
}