我正在开发一个监视Outlook共享邮箱中的多个文件夹的WPF应用程序。我已将ItemAdd和ItemRemove事件处理程序连接到Folder.Items对象。
一切都很好用了几分钟。但随着时间的推移,事件处理似乎变得“噗”。某些文件夹仍会识别添加和删除,其他文件夹只会看到删除,而其他文件夹则无视任何活动。对我而言,事件处理程序似乎是垃圾收集,但我的Items对象在它所在的类中声明为全局变量,所以我看不出它们是如何被GC出来的。
我是否应该注意Outlook Folder.Items事件的任何陷阱?我有一个以前更简单的应用程序,它通过类似的过程工作,可以在很长一段时间内正常工作。就我的旧应用程序和新应用程序之间的Item事件处理而言,没有内在差异。我真的不知道是什么导致了这一点。
以下是相关代码。为了给这个带来一些上下文,我正在做的是,对于Outlook共享邮箱中的每个文件夹,创建一个“TicketView”UserControl,它代表该文件夹的内容(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);
}
}
}
}
答案 0 :(得分:1)
不应将Outlook事件用于任何类型的同步。它们仅用于UI目的,可以在重负载下或发生网络错误时丢弃(如果您使用的是在线商店)。
您只能将事件用作代码需要尽快运行的提示。
您可以使用IExchangeExportChanges MAPI接口(仅限C ++或Delphi)来执行同步;这与Outlook用于同步其缓存文件夹的API相同。如果您不使用C ++或Delphi,则可以使用Redemption及其RDOFolderSynchronizer对象(http://www.dimastr.com/redemption/rdofoldersynchronizer.htm)