none
SyncFolderItems and SyncState RRS feed

  • Question

  • Hi, I have a question regarding the sync state, when calling SyncFolderItems.

    I have a database with all company mailboxes that will be sync'd and analyzed once daily. I want to only log emails received from the last sync. I have a windows service that will store the last sync state in the database for each mailbox. So the following day, when we the update is run again, we retrieve the last sync state (for each mailbox) from the database and we use that as a parameter for SyncFolderItems API. The problem is that the first call throws an exception (ErrorInvalidSyncStateData) and then to revcover we pass a null as the parameter.

    I have read the documentation a few times, and it mentions the sync state stored locally, but it does not mention about the validity of that parameter. 

    The following is a snippet

                int nNumberOfChanges = 0;
                List<ItemId> _ignoreCollection = new List<ItemId>();
                var enumList = _ignoreCollection.AsEnumerable();
                // For the first call, the sSyncState has to be set to null
                string sSyncState = subscriberFolderInfo.syncState; // <<<< FROM DATABASE - last sync state
                bool isEndOfChanges = false;
                do
                {
                    ChangeCollection<ItemChange> icc;
                    try
                    {
                        icc = svr.SyncFolderItems(
                            fldr, // The ID of the folder that contains the items to be synchronized.
                            PropertySet.IdOnly, // PropertySet.IdOnly will return only the ID for efficiency
                            enumList, // The optional list of item Ids that should be ignored. IEnumerable < ItemId > ignoredItemIds
                            nMaxChangesReturned, // The maximum number of changes that should be returned.
                            nNumberOfDays,
                            SyncFolderItemsScope.NormalItems,
                            sSyncState);
    
                        // Process changes
                        if (icc.Count != 0)
                        {
                            nNumberOfChanges += icc.Count;
                            // Call delegates
                            MessageItemChanges(svr, icc, dbContext, mb, subscriberFolderInfo);
                        }
    
                        // Save the sync state for use in future SyncFolderHierarchy calls.
                        sSyncState = icc.SyncState;
    
                        if (!icc.MoreChangesAvailable)
                        {
                            isEndOfChanges = true;
                        }
                    }
                    catch (ServiceResponseException ex)
                    {
                        // Get exception from using stored sync state from previous day
                        System.Diagnostics.Debug.WriteLine(string.Format("Folder sync error! Error code = {0}  Error message = {1}", ex.ErrorCode, ex.Message));
    
                        if (ex.ErrorCode == ServiceError.ErrorInvalidSyncStateData)
                        {
                            sSyncState = null;
                            icc = svr.SyncFolderItems(
                                fldr, // The ID of the folder that contains the items to be synchronized.
                                PropertySet.IdOnly, // PropertySet.IdOnly will return only the ID for efficiency
                                enumList, // The optional list of item Ids that should be ignored. IEnumerable < ItemId > ignoredItemIds
                                nMaxChangesReturned, // The maximum number of changes that should be returned.
                                nNumberOfDays,
                                SyncFolderItemsScope.NormalItems,
                                sSyncState);
    
                            // Process changes
                            if (icc.Count != 0)
                            {
                                nNumberOfChanges += icc.Count;
                                // Call delegates
                                MessageItemChanges(svr, icc, dbContext, mb, subscriberFolderInfo);
                            }
    
                            // Save the sync state for use in future SyncFolderHierarchy calls.
                            sSyncState = icc.SyncState;
    
                            if (!icc.MoreChangesAvailable)
                            {
                                isEndOfChanges = true;
                            }
    
    
                        }
                    }
    
    
                } while (!isEndOfChanges);

    I am thinking that I should use the number of days parameter for the first call to SyncFolderItems.

    I have hundreds of mailboxes every day to cycle through, so want to make this as efficient as possible.

    Any suggestions appreciated.

    Thanks,

    Tom


    • Edited by Thomas Lee3 Tuesday, January 29, 2019 9:00 PM
    Tuesday, January 29, 2019 8:59 PM