outlook的约会项目更改事件在c#中调用2次

本文关键字:调用 2次 事件 约会 项目 outlook | 更新日期: 2023-09-27 18:09:55

我正在开发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次。

有谁能给出可能的原因吗?

outlook的约会项目更改事件在c#中调用2次

首先,我建议在全局作用域中声明Items对象,以确保它不会被垃圾收集器扫过。例如,您可以在Startup事件处理程序之外声明Items对象。

Items类的ItemChange事件在指定集合中的项发生更改时触发。因此,每次更改任何属性时都会触发它。

如果条目被保存多次,事件将被触发多次。你应该准备好处理以下情况:

事件处理程序应该做什么?为什么这是一个问题?

我还没有找到任何完全明确的解决方案。我实现的最好的想法是创建已经处理的任务列表,并为它们设置时间有效性。

在事件开始时,我检查是否有任何已处理的任务过期,并将其从列表中删除。这样我保持列表小,防止内存泄漏。

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

如果您对工作解决方案感兴趣,您可以在存储库中找到上述代码。