none
Not getting the updated count of recurrence exception in Items_ItemChange event in VSTO Application RRS feed

  • Question

  •  Hi

    We have VSTO application developed with VSTO2007 and we are using same VSTO on Outlook2010 Now we are facing  issue with getting updated count of recurrence exception in Items_ItemChange event.

    Steps:

    1. Create recurrence booking for 5 days

    2. Reschedule\ delete single occurrence.

    3. Check exception count.

    We are always getting exception count =0 for newly created booking.

    If we close & open outlook and try to reschedule\delete same booking it works fine.

    Please find below code:

    public partial class ThisAddIn
        {
            private List<string> _folderPaths = new List<string>();
            private List<Items> _calendarItems = new List<Items>();
            private List<MAPIFolderEvents_12_Event> _MAPI12Events = new List<MAPIFolderEvents_12_Event>();
            public static bool _isRescheduleProgress = false;
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {

                Outlook.MAPIFolder defaultFolder = this.Application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
                Items items = defaultFolder.Items;

                _calendarItems.Add(items);
                //newCalendarFolder = defaultFolder;
                MAPIFolderEvents_12_Event mapi12Event = (MAPIFolderEvents_12_Event)defaultFolder;
                _MAPI12Events.Add(mapi12Event);
                items.ItemChange += new ItemsEvents_ItemChangeEventHandler(Items_ItemChange);
                items.ItemAdd += new ItemsEvents_ItemAddEventHandler(items_ItemAdd);

            }

            void items_ItemAdd(object Item)
            {


                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            }


            void Items_ItemChange(object Item)
            {
                try
                {
                    if(Item is AppointmentItem)
                    {
                    AppointmentItem ap = ((AppointmentItem)Item);
                    RecurrencePattern rp = ap.GetRecurrencePattern();
                    Outlook.Exceptions ex= rp.Exceptions;
                    System.Windows.Forms.MessageBox.Show(ex.Count.ToString());
                    ReleaseObject(ap);
                    ReleaseObject(rp);
                    ReleaseObject(ex);
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();

                    }
                }
                catch (System.Exception ex)
                { }
            }

            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
            }

            /// <summary>
            /// To release object
            /// </summary>
            /// <param name="obj">Object</param>
            public static void ReleaseObject(Object obj)
            {
                try
                {
                    int i = 1;
                    do
                    {
                        i = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                    }
                    while (i > 0);
                }
                catch
                { }
                finally
                {
                    obj = null;
                }
            }


            #region VSTO generated code

            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }

            #endregion
        }

    Kindly help ASAP....

    Regards

    Neeraj B.

                                               

    Neeraj

    Tuesday, August 5, 2014 9:39 AM

Answers

  • Where are you saving the item? You should save it to commit any changes.

    Ken Slovak MVP - Outlook

    • Marked as answer by Neerajb Thursday, August 28, 2014 8:53 AM
    Tuesday, August 5, 2014 5:56 PM
    Moderator

All replies

  • Hello Neeraj,

    First of all, I have noticed that you don't release underlying COM objects instantly. For example:

    Application.Session.GetDefaultFolder


    The Session property of the Application class returns an instance of the Namespace class which should be released after. Then the GetDefaultFolder method of the Namespace class returns an instance of the MAPIFolder class which should be released after also.

    There is no need to use the following code if you release underlying COM objects instantly:

    GC.Collect();
    GC.WaitForPendingFinalizers();

    Moreover, swiping the heap is a time-consuming task.

    Anyway, here is what the MSDN library states for the Exception object:

    When you work with recurring appointment items, you should release any prior references, obtain new references to the recurring appointment item before you access or modify the item, and release these references as soon as you are finished and have saved the changes. This practice applies to the recurring AppointmentItem object, and any Exception or RecurrencePattern object. To release a reference in Visual Basic for Applications (VBA) or Visual Basic, set that existing object to Nothing. In C#, explicitly release the memory for that object. For a code example, see the topic for the AppointmentItem object.

    Note that even after you release your reference and attempt to obtain a new reference, if there is still an active reference, held by another add-in or Outlook, to one of the above objects, your new reference will still point to an out-of-date copy of the object. Therefore, it is important that you release your references as soon as you are finished with the recurring appointment.

    It looks like this is exactly your case.

    Tuesday, August 5, 2014 10:32 AM
  • I have modified code as you have suggested as below but still we are facing issue

    Kindly help!!!!

    It is working code you can modify if you think there is any issue

     public partial class ThisAddIn
        {
            private List<string> _folderPaths = new List<string>();
            private List<Items> _calendarItems = new List<Items>();
            private List<MAPIFolderEvents_12_Event> _MAPI12Events = new List<MAPIFolderEvents_12_Event>();
            public static bool _isRescheduleProgress = false;
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {

                Outlook.MAPIFolder defaultFolder = this.Application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
                Items items = defaultFolder.Items;
                
                _calendarItems.Add(items);
                //newCalendarFolder = defaultFolder;
                MAPIFolderEvents_12_Event mapi12Event = (MAPIFolderEvents_12_Event)defaultFolder;
                _MAPI12Events.Add(mapi12Event);
                items.ItemChange += new ItemsEvents_ItemChangeEventHandler(Items_ItemChange);
                items.ItemAdd += new ItemsEvents_ItemAddEventHandler(items_ItemAdd);
                ReleaseObject(defaultFolder);
                ReleaseObject(items);
            }
            
            void items_ItemAdd(object Item)
            {
                

                //GC.Collect();
                //GC.WaitForPendingFinalizers();
                //GC.Collect();
                if (Item is AppointmentItem)
                {
                    AppointmentItem ap = ((AppointmentItem)Item);
                    RecurrencePattern rp = ap.GetRecurrencePattern();
                    Outlook.Exceptions ex = rp.Exceptions;
                    System.Windows.Forms.MessageBox.Show(ex.Count.ToString());
                    ReleaseObject(ap);
                    ReleaseObject(rp);
                    ReleaseObject(ex);
                    ReleaseObject(Item);
                }
            }


            void Items_ItemChange(object Item)
            {
                try
                {
                    if(Item is AppointmentItem)
                    {
                    AppointmentItem ap = ((AppointmentItem)Item);
                    RecurrencePattern rp = ap.GetRecurrencePattern();
                    Outlook.Exceptions ex= rp.Exceptions;
                    System.Windows.Forms.MessageBox.Show(ex.Count.ToString());
                    ReleaseObject(ap);
                    ReleaseObject(rp);
                    ReleaseObject(ex);
                    //GC.Collect();
                    //GC.WaitForPendingFinalizers();
                    GC.Collect();
                    ReleaseObject(Item);

                    }
                }
                catch (System.Exception ex)
                { }
            }

            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
            }

            /// <summary>
            /// To release object
            /// </summary>
            /// <param name="obj">Object</param>
            public static void ReleaseObject(Object obj)
            {
                try
                {
                    int i = 1;
                    do
                    {
                        i = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                    }
                    while (i > 0);
                }
                catch
                { }
                finally
                {
                    obj = null;
                }
            }


            #region VSTO generated code

            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }

            #endregion
        }

    Regards

    Neeraj B


    Neeraj

    Tuesday, August 5, 2014 1:49 PM
  • There is no to release the item passed as a parameter to the ItemCHange event handler. Moreover, you release it twice.
    Tuesday, August 5, 2014 1:53 PM
  • Where are you saving the item? You should save it to commit any changes.

    Ken Slovak MVP - Outlook

    • Marked as answer by Neerajb Thursday, August 28, 2014 8:53 AM
    Tuesday, August 5, 2014 5:56 PM
    Moderator