Search code examples
c#.netexchangewebservices

ExchangeService FindItems Suddenly Intermittently Not Working


This has been working perfectly for probably a year or more, then suddenly, I think as of Saturday October 12th it started failing (FindResults returns no items);

        //Tag the sent email so we can pull it back in a moment
        Guid myPropertySetId = new Guid("{375a1079-a049-4c2d-a2e1-983d588cbed4}");
        ExtendedPropertyDefinition myExtendedPropertyDefinition = new ExtendedPropertyDefinition(myPropertySetId, "TelEmailGuid", MapiPropertyType.String);
        Guid telEmailGuid = Guid.NewGuid();
        message.SetExtendedProperty(myExtendedPropertyDefinition, telEmailGuid.ToString());

        //Send the email
        message.SendAndSaveCopy(completedFolder);

        //Find the sent email
        ItemView view = new ItemView(1);
        SearchFilter searchFilter = new SearchFilter.IsEqualTo(myExtendedPropertyDefinition, telEmailGuid.ToString());
        view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
        FindItemsResults<Item> findResults = service.FindItems(completedFolder, searchFilter, view);

        return DownloadEmail(findResults.FirstOrDefault().Id.ToString());

I tried tweaking things a little to wait before trying to find the e-mail, this has helped (now maybe 10% succeed). So, I then added a loop, so if not found it will try again a few times. But it seems that if it isn't found the first time, it is not found on subsequent attempts;

        //Tag the sent email so we can pull it back in a moment
        Guid myPropertySetId = new Guid("{375a1079-a049-4c2d-a2e1-983d588cbed4}");
        ExtendedPropertyDefinition myExtendedPropertyDefinition = new ExtendedPropertyDefinition(myPropertySetId, "TelEmailGuid", MapiPropertyType.String);
        Guid telEmailGuid = Guid.NewGuid();
        message.SetExtendedProperty(myExtendedPropertyDefinition, telEmailGuid.ToString());

        //Send the email
        message.SendAndSaveCopy(completedFolder);

        //Find the sent email
        ItemView view = new ItemView(1);
        SearchFilter searchFilter = new SearchFilter.IsEqualTo(myExtendedPropertyDefinition, telEmailGuid.ToString());
        view.PropertySet = new PropertySet(BasePropertySet.IdOnly);

        int attempt = 1;
        System.Threading.Thread.Sleep(1000);
        FindItemsResults<Item> findResults = service.FindItems(completedFolder, searchFilter, view);

        while (findResults.TotalCount == 0 && attempt < 5)
        {
            findResults = service.FindItems(completedFolder, searchFilter, view);
            attempt++;
        }

        return DownloadEmail(findResults.FirstOrDefault().Id.ToString());

Does anyone have any suggestions? I suspect it is a Microsoft issue but perhaps a different approach might allow us to workaround the issue.


Solution

  • It sounds like its an issue with the Search timing out because your not searching an indexed property as the FolderItem Count grow the performance of the search will decline over time (also other factors like server load etc will have a direct effect when searching for item in a Folder with a large item count).

    Your search looks pretty static so you could create a Search Folder https://learn.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/dd633690(v%3Dexchg.80) which would optimize the search.

    The other thing you maybe be able to do is add a DateTime restriction for the search eg I have code that searches for messages based on the Internet MessageId and it has a similar problem when Item counts get large the search times out. So because I know what I'm searching for are always recent email adding a Date Time restriction fixed the issue in this instance eg

            SearchFilter internetMessageIdFilter = new SearchFilter.IsEqualTo(PidTagInternetMessageId, InternetMessageId);
            SearchFilter DateTimeFilter = new SearchFilter.IsGreaterThan(EmailMessageSchema.DateTimeReceived, DateTime.Now.AddDays(-1));
            SearchFilter.SearchFilterCollection searchFilterCollection= new SearchFilter.SearchFilterCollection(LogicalOperator.And);
            searchFilterCollection.Add(internetMessageIdFilter);
            searchFilterCollection.Add(DateTimeFilter);