События папки Outlook случайно перестают работать в общем почтовом ящике

Я работаю над приложением WPF, которое отслеживает многочисленные папки в общем почтовом ящике Outlook. Я подключил обработчики событий ItemAdd и ItemRemove к объекту Folder.Items.

Все отлично работает в течение нескольких минут. Но с течением времени обработка событий, кажется, идет "пуф". Некоторые папки по-прежнему распознают добавление и удаление, другие видят только удаления, а другие не видят никаких действий. Мне кажется, что обработчики событий собираются мусором, но мой объект Items объявлен как глобальная переменная в классе, в котором он находится, поэтому я не вижу, как они могут быть GC-out.

Есть ли какие-либо подводные камни, о которых мне следует знать в событиях 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);
            }
        }
    }
}

1 ответ

Решение

События Outlook не должны использоваться для какой-либо синхронизации. Они предназначены для использования только в целях пользовательского интерфейса и могут быть отброшены при больших нагрузках или при возникновении сетевой ошибки (если вы используете интернет-магазин).

Вы можете использовать события только как подсказку, что ваш код должен запускаться раньше, а не позже.

Вы можете использовать интерфейс MAPI IExchangeExportChanges (только C++ или Delphi) для выполнения синхронизации; это тот же API, который используется Outlook для синхронизации его кэшированных папок. Если вы не используете C++ или Delphi, вы можете использовать Redemption и его объект RDOFolderSynchronizer ( http://www.dimastr.com/redemption/rdofoldersynchronizer.htm).

Другие вопросы по тегам