Outlook文件夹事件在共享邮箱上随机停止工作

Outlook文件夹事件在共享邮箱上随机停止工作,outlook,wpf-controls,mapi,public-folders,Outlook,Wpf Controls,Mapi,Public Folders,我正在开发一个WPF应用程序,它监视Outlook共享邮箱中的多个文件夹。我已将ItemAdd和ItemRemove事件处理程序连接到文件夹.Items对象 几分钟内一切都很好。但随着时间的推移,事件处理似乎变得“糟糕”。某些文件夹仍能识别添加和删除,其他文件夹只能看到删除,而其他文件夹对任何活动都视而不见。在我看来,事件处理程序似乎正在被垃圾收集,但我的Items对象在它所在的类中声明为全局变量,因此我不知道如何将它们GC化 Outlook Folder.Items事件中是否有我应该注意的陷阱

我正在开发一个WPF应用程序,它监视Outlook共享邮箱中的多个文件夹。我已将ItemAdd和ItemRemove事件处理程序连接到文件夹.Items对象

几分钟内一切都很好。但随着时间的推移,事件处理似乎变得“糟糕”。某些文件夹仍能识别添加和删除,其他文件夹只能看到删除,而其他文件夹对任何活动都视而不见。在我看来,事件处理程序似乎正在被垃圾收集,但我的Items对象在它所在的类中声明为全局变量,因此我不知道如何将它们GC化

Outlook Folder.Items事件中是否有我应该注意的陷阱?我有一个以前的、更简单的应用程序,它通过类似的过程工作,可以在较长的时间内正常工作。就项目事件处理而言,我的旧应用程序和这个新应用程序之间没有本质上的区别。我真的不知道是什么导致了这一切

以下是相关代码。为了提供一些上下文信息,我要做的是,为Outlook共享邮箱中的每个文件夹创建一个“TicketView”用户控件,该控件表示该文件夹的内容(MailItems)。这个TicketView是一个简单的列表框,可能包含0到几十个邮件项——没有多余的内容

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);
            }
        }
    }
}
public部分类TicketView:UserControl
{
私有文件夹_thisFolder=null;
私有TicketCollection\u thistticketcoll=null;
私有项_thisItems=null;
公共TicketView(文件夹)
{
初始化组件();
_thisTicketColl=this.FindResource(“TicketCollection”)作为TicketCollection;
_thisFolder=文件夹;
_thisItems=文件夹.Items;
SetFolderEvents();
刷新();
}
私有void SetFolderEvents()
{
_thisItems.ItemAdd+=新ItemsEvents\u ItemAddEventHandler(委托
{
刷新();
});
_thisItems.ItemRemove+=新ItemsEvents\u ItemRemoveEventHandler(委托
{
刷新();
});
}
公共无效刷新()
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=新的DoWorkEventHandler(委托(对象发送方,DoWorkEventArgs e)
{
字符串[]字段=新字符串[]{“Subject”、“SenderName”、“SentOn”、“EntryID”};
var olTable=TicketMonitorStatics.GetOutlookTable(_thisFolder,fields,filter);
olTable.Sort(“SentOn”,true);
var refreshedList=新列表();
而(!olTable.EndOfTable)
{
var olRow=olTable.GetNextRow();
刷新列表。添加(新票证)
{
Subject=olRow[“Subject”],
Sender=olRow[“SenderName”],
SentOn=olRow[“SentOn”],
EntryID=olRow[“EntryID”]
});
};
e、 结果=刷新列表;
});
worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(委托(对象发送方,runworkercompletedeventhargs e)
{
var refreshedList=e.结果为列表;
更新列表(刷新列表);
worker.Dispose();
});
worker.RunWorkerAsync();
}
私有void updateciketlist(List newList)
{
_thisTicketColl.Clear();
foreach(新列表中的票证t)
{
_此ticketcoll.Add(t);
}
}
}
}

Outlook事件不应用于任何类型的同步。它们被设计为仅用于UI目的,并且可以在重载或发生网络错误(如果您使用在线商店)时删除

您只能使用事件作为提示,提示您的代码需要尽早运行


您可以使用IExchangeExportChanges MAPI接口(仅限C++或Delphi)执行同步;这与Outlook用于同步其缓存文件夹的API相同。如果你不使用C++或Delphi,你可以使用赎回及其RDOFoelSimulink对象()< /P>我会接受这个建议,但这不是这里发生的事情。我尝试了一个例程来清除ItemAdd和ItemRemove事件处理程序,然后每隔5分钟(使用计时器)重新设置它们。在我重置_thisItems对象本身之前,这也不起作用。我删除了事件,null _thisItems,将其重新设置为_thisItems=_thisFolder.Items,然后再次设置事件——这似乎已经纠正了问题。我只是不明白为什么它发生在这个应用而不是我的另一个。如果有网络问题,通知通道会被重置,你会看到这个问题。同样,MAPI事件不可靠,您无法使其可靠。