0

Outlook 共有メールボックス内の多数のフォルダーを監視する WPF アプリケーションに取り組んでいます。ItemAdd および ItemRemove イベント ハンドラーを Folder.Items オブジェクトに接続しました。

すべてが数分間うまく機能します。しかし、時間が経つにつれて、イベント処理は「だめ」になるようです。一部のフォルダは引き続き追加と削除を認識し、他のフォルダは削除のみを表示しますが、他のフォルダはアクティビティを認識しません. 私には、イベント ハンドラーがガベージ コレクションされているように見えますが、私の Items オブジェクトは、それが置かれているクラスでグローバル変数として宣言されているため、それらがどのように GC されるのかわかりません。

Outlook Folder.Items イベントで注意すべき落とし穴はありますか? 同様のプロセスで動作する以前のより単純なアプリケーションがあり、長期間にわたって正常に動作します。Item イベント処理に関する限り、私の古いアプリとこの新しいアプリの間に本質的な違いはありません。私はこれを引き起こしているものについて本当に途方に暮れています。

以下は関連するコードです。これにいくつかのコンテキストをもたらすために、私がやっていることは、Outlook 共有メールボックスの各フォルダーに対して、そのフォルダーの内容 (MailItems) を表す "TicketView" UserControl が作成されることです。この TicketView は、0 から数十個の MailItems を含む単純な ListBox であり、余分なものはありません。

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);
            }
        }
    }
}
4

1 に答える 1

1

Outlookイベントは、いかなる種類の同期にも使用しないでください。これらはUIの目的でのみ使用するように設計されており、高負荷の場合、またはネットワークエラーが発生した場合(オンラインストアを使用している場合)にドロップできます。

イベントは、コードを後でではなく早く実行する必要があるというヒントとしてのみ使用できます。

IExchangeExportChanges MAPIインターフェイス(C ++またはDelphiのみ)を使用して同期を実行できます。これは、Outlookがキャッシュされたフォルダを同期するために使用するのと同じAPIです。C ++またはDelphiを使用していない場合は、RedemptionとそのRDOFolderSynchronizerオブジェクト(http://www.dimastr.com/redemption/rdofoldersynchronizer.htm)を使用できます。

于 2013-03-10T16:16:33.190 に答える