Событие перспективы изменения пункта назначения вызывается 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 происходит при изменении элемента в указанной коллекции. Таким образом, он срабатывает каждый раз, когда вы меняете любое свойство.