Событие перспективы изменения пункта назначения вызывается 2 раза в C#

Я разрабатываю надстройку для Outlook, для которой мне нужно отслеживать события добавления, изменения и удаления событий. Поэтому я использую приведенный ниже код.

   public Microsoft.Office.Interop.Outlook.Application app = null;
   public Outlook.NameSpace ns = null;
   public Outlook.MAPIFolder calendar = null;
   public Outlook.Items appointments = null;

private void ThisAddIn_Startup(object sender, System.EventArgs e) 
{
    app = Application;
    ns = app.GetNamespace("mapi");
    ns.Logon("", "", true, true);
    calendar = ns.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
    appointments = calendar.Items;

    appointments.ItemAdd += Item_Add;
    appointments.ItemChange += Item_Change;
    appointments.ItemRemove += Item_Remove;
}

private void Item_Add(object item) 
{
   // some logic
}

private void Item_Change(object item) 
{
  // some logic
}

private void Item_Remove() 
{
  // some logic
}

Теперь, когда я добавляю встречу в то время Item_Add событие называется.

Когда я обновляю созданную встречу, тогда Item_Change событие происходит 2 раза.

Я не смог понять, почему стреляет 2 раза.

Кто-нибудь может привести возможную причину этого?

3 ответа

Я не нашел абсолютно ясного решения. Лучшая идея, которую я реализовал, - создать список задач, которые уже были обработаны, и установить для них срок действия.

В начале события я проверяю, устарела ли какая-либо из обработанных задач, и удаляю ее из списка. Таким образом, я сохраняю небольшой список и защищаю от утечки памяти.

class TaskItem
{
    private int milisecods = 200;
    DateTime Now
    {
        get
        {
            return DateTime.Now;
        }
    }

    public TaskItem()
    {
        this.Created = Now;
    }

    private DateTime Created;

    public string EntryId { get; set; }

    public bool OutDated
    {
        get
        {
            return this.Created.AddMilliseconds(milisecods) > Now;
        }
    }
}

List<TaskItem> TaskItemsList = new List<TaskItem>();

private void TaskItems_ItemChange(object Item)
{
    this.TaskItemsList.RemoveAll(x => x.OutDated);
    MailItem element = Item as MailItem;
    if (element != null)
    {
        if (element.FlagStatus == OlFlagStatus.olFlagComplete)
        {
            if (this.TaskItemsList.Any(x => x.EntryId == element.EntryID) == false)
            {
                this.TaskItemsList.Add(new TaskItem { EntryId = element.EntryID });
                new WcfClient().ProcesOutlookTask(TaskActionType.Finished);
            }
        }
    }
}

Если вас интересует работающее решение, вы можете найти приведенный выше код в репозитории.

Событие запускается более одного раза, если элемент был сохранен несколько раз. Вы должны быть готовы справиться с такими ситуациями, как.

Что должен делать ваш обработчик событий? Почему это проблема?

Прежде всего, я бы рекомендовал объявить Items объект в глобальной области видимости, чтобы убедиться, что сборщик мусора не ударил его. Например, вы можете объявить Items объект вне обработчика событий автозагрузки.

Событие ItemChange класса Items происходит при изменении элемента в указанной коллекции. Таким образом, он срабатывает каждый раз, когда вы меняете любое свойство.

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