【问题标题】:Outlook Folder events randomly stop working on Shared MailboxOutlook 文件夹事件在共享邮箱上随机停止工作
【发布时间】:2013-02-25 18:33:21
【问题描述】:

我正在开发一个 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);
            }
        }
    }
}

【问题讨论】:

    标签: outlook wpf-controls mapi public-folders


    【解决方案1】:

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

    您只能将事件用作代码需要尽快运行而不是稍后运行的提示。

    您可以使用 IExchangeExportChanges MAPI 接口(仅限 C++ 或 Delphi)执行同步;这与 Outlook 用于同步其缓存文件夹的 API 相同。如果您不使用 C++ 或 Delphi,则可以使用 Redemption 及其 RDOFolderSynchronizer 对象 (http://www.dimastr.com/redemption/rdofoldersynchronizer.htm)

    【讨论】:

    • 我会接受建议,但这不是这里发生的事情。我尝试了一个例程来清除 ItemAdd 和 ItemRemove 事件处理程序,然后每 5 分钟重新设置一次(使用计时器)。在我重置 _thisItems 对象本身之前,这也不起作用。我删除了事件,null _thisItems,将其重新设置为 _thisItems = _thisFolder.Items,然后再次设置事件 - 这似乎已经纠正了问题。我只是不明白为什么它发生在这个应用程序而不是我的另一个应用程序中。
    • 如果有网络问题,通知通道被重置,你会看到这个问题。同样,MAPI 事件不可靠,您无法使它们可靠。
    猜你喜欢
    • 1970-01-01
    • 2019-08-18
    • 2018-11-20
    • 1970-01-01
    • 2016-09-28
    • 2017-06-05
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多