Sync problems with Office 365 and ADXOutlookItemsEvents

Add-in Express™ Support Service
That's what is more important than anything else

Sync problems with Office 365 and ADXOutlookItemsEvents
 
Bert Sinnema


Guest


Hi ADX,

In one of our add-ins I have some code that has been working really well for the past two years. For the past years we and some of our customers are using Office 365 with Exchange online. Suddenly lately we are having some sync problems.

I have started a little lab project to identify if nothing else was causing the problems and I am able to reproduce it. What we do is listen to Items events on the Sent Items folder. When a new MailItem is added, based on a few conditions we're adding an attachment. This used to work fine but it seems that nowadays this causes sync problems. Outlook says: 'this is the most recent version but you made changes to another copy'

Here's the simplified code:

        public override void ItemAdd(object item, object sourceFolder)
        {

            if (item is Outlook.MailItem)
            {
             
                Outlook.MailItem mailItem = item as Outlook.MailItem;
                Outlook.Attachments attachments = mailItem.Attachments as Outlook.Attachments;

                const string location = "C:\Users\BertSinnema\Desktop\1.pdf";
                Outlook.Attachment att = attachments.Add(location, Outlook.OlAttachmentType.olByValue);

                //Release att
                Marshal.ReleaseComObject(att);
                //Release attachments
                Marshal.ReleaseComObject(attachments);
                

                // Save mailitem
                mailItem.Save();

                // Release mailitem COM
                Marshal.ReleaseComObject(mailItem);
            }

            base.ItemAdd(item, sourceFolder);
        }


Is there a way I can control this sync so the altered version of the MailItem is synced and becomes the version I see in the Sent Items folder?

Cheers
Posted 15 Jun, 2018 02:23:26 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Hello Bert,

Bert Sinnema writes:
public override void ItemAdd(object item, object sourceFolder)
...
Outlook.MailItem mailItem = item as Outlook.MailItem;
...
// Release mailitem COM
Marshal.ReleaseComObject(mailItem);
...
base.ItemAdd(item, sourceFolder);


Actually item and mailItem variables point to the same COM object. Assuming that ItemAdd overrides ADXOutlookItemsEvents.ItemAdd, the code above effectively breaks one of Add-in Express rules; the rule is: Don't release COM objects passed to your code in parameters of Add-in Express events.

Try to comment out this call: Marshal.ReleaseComObject(mailItem). Does it help?


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jun, 2018 06:10:16 Top
Bert Sinnema


Guest


Hi Andrei,

Thanks for the tip. I think now I know all the rules of releasing. However, removing the call to release mailItem doesn't do the trick. I still end up with a version conflict. Is there maybe a way to pause sync on the folder before send and start it back up after the ItemAdd event?

I feel the mailItem has already been synced to the Sent items folder before I run my code.
Posted 15 Jun, 2018 06:54:31 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Could you please provide me with a sample project demonstrating the issue?


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jun, 2018 06:58:38 Top
Bert Sinnema


Guest


Hi Andrei,

https://personalbertsinnema.blob.core.windows.net/labs/OutlookSyncHell.zip

Note that I am on Office 365 with exchange online backend. I think I run Outlook in cached mode as do most of our customers. Also not that this code adds an attachment to any mail i send, so be careful to whom you're sending :-)

Repro steps:


  • Send a new email
  • In sent items you see the sent mail with attachment
  • Restart Outlook or manually sync folder
  • Now you have a sync conflict


What also works to see the sync mess in the making. Have a window opened on the sent items in OWA. You'll see that the version without the attachment is synced with the server and the local version is altered.

Good luck!
Posted 15 Jun, 2018 08:48:59 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Than you, Bert.

It looks like Outlook is busy with some task.

Make sure all other COM add-ins are turned off.

I suggest that you use the machinery that we describe in section Wait a little at https://www.add-in-express.com/docs/net-office-tips.php#wait-a-little to create a small delay; perform your task after the delay is over. If the issue persists, use System.Windows.Fowm.Timer to create a more significant delay, say, a couple of seconds.


Andrei Smolin
Add-in Express Team Leader
Posted 15 Jun, 2018 09:30:58 Top
Bert Sinnema


Guest


Hi Andrei,

Thanks. All other COM addins have been turned off. I always do this with my lab project to get the purest environment.
I am not very familiar with timers and how to access the mailitem from a timed listener. I'm guessing a Thread.Sleep would simply block the operation.

Could you help me on my way with an example based on my code?

Cheers
Posted 15 Jun, 2018 11:29:00 Top
Bert Sinnema


Guest


Hi Andrei,

https://personalbertsinnema.blob.core.windows.net/labs/OutlookSyncHellWithWaitALittle.zip

I have implemented the wait a little concept in my lab project. What I do is on the ADXOutlookItemsEvents.ItemAdd event:

        public override void ItemAdd(object item, object sourceFolder)
        {

            if (item is Outlook.MailItem)
            {
                // Grabbing the mailitem which does not have to be released as it is a parameter of the event
                Outlook.MailItem mailItem = item as Outlook.MailItem;
                // Grab the entry id
                var entryId = mailItem.EntryID;

                // Create a seperate thread that will queue the operation
                // Should not be a problem as the Outlook model is not used in the seperate thread
                Task.Factory.StartNew(() =>
                {
                    // Wait 5 seconds
                    Thread.Sleep(5000);
                    // Call a method that queues the operation and sends a message to the main thread
                    AddinModule.CurrentInstance.AddToAttachmentQueue(entryId);
                });

            }

            base.ItemAdd(item, sourceFolder);
        }


The call to AddinModule.AddToAttachmentQueue on the CurrentInstance is as follows:

        // Called from other thread
        internal void AddToAttachmentQueue(string entryID)
        {
            // Add the entry to the queue
            itemsQueue.Enqueue(entryID);
            // Send a message to the main thread
            SendMessage(X_ADD_ATTACHMENT);
        }


And the AddinModule.OnSendMessage has the following event listener:

        // Run on OL main thread
        private void AddinModule_OnSendMessage(object sender, ADXSendMessageEventArgs e)
        {
            // If the message is a message we sent
            if (e.Message == X_ADD_ATTACHMENT)
            {
                // dequeue an entry id
                var entryId = (string) itemsQueue.Dequeue();
                
                // Do the operation
                MailItemHelper.AddAttachment("C:\Users\X\Desktop\1.pdf" , entryId);
            }
        }



And the helper adds the attachment:

public static void AddAttachment(string source, string entryId)
        {

            Outlook.NameSpace nameSpace = AddinModule.CurrentInstance.OutlookApp.GetNamespace("MAPI");

            var item = nameSpace.GetItemFromID(entryId);

            if (item != null && item is Outlook.MailItem)
            {
                //Don't release this as it is a parameter of an ADX event
                Outlook.MailItem mailItem = item as Outlook.MailItem;

                Outlook.Attachments attachments = mailItem.Attachments as Outlook.Attachments;

                Outlook.Attachment att = attachments.Add(source, Outlook.OlAttachmentType.olByValue);

                //Release att
                Marshal.ReleaseComObject(att);
                //Release attachments
                Marshal.ReleaseComObject(attachments);


                // Save mailitem
                mailItem.Save();

                Marshal.ReleaseComObject(mailItem);
            }

            Marshal.ReleaseComObject(nameSpace);
        }


This all works really well. The event is nicely triggered through the internal messaging system as it should. All COM's seem to be released following the rules. However the problem persists. I'm guessing it has everything to do with synchronizing a folders local cache with the server. I think once a mail is sent, it's synced to the server. Then after 5 seconds we alter the e-mail that was already synced and we end up with a different version, basically a dirty version.

Do you think there would be a way to stop the syncing of the sent items folder on initialize and then sync items manually one by one? or that we pick smart times to enable and disable sync on the folder?

Cheers
Posted 16 Jun, 2018 06:08:02 Top
Andrei Smolin


Add-in Express team


Posts: 18793
Joined: 2006-05-11
Hello Bert,

The code looks perfectly okay.

What Outlook build are you using? Also, could you please check if you add an ItemChange a while after you receive ItemAdd (with no your other code involved)? Just recently, I run in an unexpected ItemChange event occurring in 3-15 seconds after creating and saving an AppointmentItem (this raised ItemAdd as expected); I use the latest Insider edition of Outlook, cached mode with Exchange Online.


Andrei Smolin
Add-in Express Team Leader
Posted 18 Jun, 2018 03:30:26 Top
Bert Sinnema


Guest


Hi Andrei,

I am on version 1806 build 10228.20062 in cached mode with Exchange Online.

When creating a new MailItem (by sending an empty one to a random address) and I don't execute my code in ItemAdd, ItemChange fires 4 times in a row and a 5th time a 1-5 seconds later.

I feel like the 5th one might be before or after sync. It would be great if we could merge versions or flag the latest version through the Office Interop, but it seems we can't

Any other ideas?

Cheers
Posted 18 Jun, 2018 06:46:05 Top