我正在开发一个WPF应用程序,它可以监控Outlook共享邮箱中的多个文件夹。我已经将ItemAdd和ItemRemove事件处理程序连接到一个文件夹。项目对象。
在几分钟内一切都很好。但随着时间的推移,事件处理似乎"噗"了一声。一些文件夹仍然可以识别添加和删除,其他文件夹只能看到删除,而其他文件夹则看不到任何活动。对我来说,事件处理程序似乎正在被垃圾收集,但我的Items对象被声明为它所在类中的全局变量,所以我不知道它们如何被GC出来。
有什么陷阱我应该知道Outlook文件夹。项目事件吗?我以前有一个更简单的应用程序,它通过类似的过程工作,可以很好地工作很长一段时间。就Item事件处理而言,我的旧应用程序和这个新应用程序之间没有本质上的区别。我真不知道是什么原因造成的。
下面是相关代码。为了给这个带来一些背景,我正在做的是,为Outlook共享邮箱中的每个文件夹创建一个"TicketView"UserControl,它代表该文件夹的内容(MailItems)。这个TicketView是一个简单的ListBox,可以包含0到几十个mailitem——没有多余的。
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);
}
}
}
}
Outlook事件不应该用于任何类型的同步。它们被设计为仅用于UI目的,并且可以在重载或网络错误发生时(如果您使用的是在线商店)删除。
你可以使用事件来提示你的代码需要尽快运行。
您可以使用IExchangeExportChanges
MAPI接口(仅限c++或Delphi)执行同步;这是Outlook用来同步其缓存文件夹的相同API。如果你不使用c++或Delphi,你可以使用Redemption(我是它的作者)和它的RDOFolderSynchronizer对象。