问题
I am developing outlook add-in for which I have to track appointment item add, change & remove events. So I am using bellow code.
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
}
Now when I add meeting at that time Item_Add
event is called.
When I update that created meeting then Item_Change
event is fired 2 times.
I not able to get why it is firing 2 times.
Can any one give possible reason for it ?
回答1:
First of all, I'd recommend declaring the Items
object at the global scope to make sure it is not swiped by the garbage collector. For example, you may declare the Items
object outside of the Startup event handler.
The ItemChange event of the Items class is fired when an item in the specified collection is changed. So, it is fired each time you change any property.
回答2:
The event gets fired more than once if the item is saved multiple times. You should be prepared to handle situations like.
What does your event handler supposed to do? Why is this a problem?
回答3:
I haven't found any completely clear solution. The best idea which I implemented was to create list of Tasks which already had been processed and set the time validity for them.
At the beginning of the event I check if any of the processed task is outdated and remove it from the list. This way I keep list small and protect against memory leak.
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);
}
}
}
}
If you are interested in the working solution you can find above code in the repository.
来源:https://stackoverflow.com/questions/32205255/appointment-item-change-event-of-outlook-called-2-times-in-c-sharp