'Outlook VSTO plugin stops executing while iterating over contacts in default contacts folder

I wrote an Outlook plugin in which a method searches for a contact's phone number by searching the default contact folder for contacts with a specified email address.

The for loop in the sample below simply seems to stop running for some of my outlook users. The "processing contact" message is the last message logged, and the "Iteration completed" message never appears.

Also, seemingly no exceptions occur (I can't test this on a development box right now and I'm depending on my logged debug messages), the method simply seems to stop in the midst of the for loop and the method calling the method below does not continue executing.

var phoneNumbers = new List<PhoneNumberModel>();
var mailAddress = "[email protected]";

var contacts = Application.ActiveExplorer().Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
if(contacts != null)
{ 
    logger.Debug($"Iterating contact items...");
    foreach (ContactItem foundContact in contacts.Items)
    {
        logger.Debug("Processing contact: {contact.CompanyAndFullName}");
        if ((foundContact.Email1Address?.ToLower() ?? "").Contains(mailAddress.ToLower()))
        {
            if (!string.IsNullOrWhiteSpace(foundContact.BusinessTelephoneNumber))
            {
                phoneNumbers.Add(new PhoneNumberModel { NumberType = "Business phone number", PhoneNumber = foundContact.BusinessTelephoneNumber });
            }
        }

        logger.Debug($"AddPhoneNumbersFromDefaultAddressBook() Iteration completed");
    }
}

I suspected an API timeout of some sort, so I wrapped the call to the above method in a timeout handler:

int timeout = 1000;
var task = SomeOperationAsync();
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
    // task completed within timeout
} else { 
    // timeout-logic
}
// further-logic

The timeout-logic and further-logic does not execute.

Any ideas what could be going on here?



Solution 1:[1]

Your code assumes you can only have ContactItem objects in the Contacts folder. It will fail if you have a DistItem object.

Also keep in mind that you cannot access Outlook Object Model on a secondary thread (such as that used by the Task object). Only Extended MAPI objects can be accessed from secondary threads, but that requires Extended MAPI. If using Redemption (I am its author) is an option, is RDO family of objects wraps Extended MAPI and can be accessed from secondary threads.

Thirdly, never loop through all items in a a folder, let Items.Find/FindNext or Items.Restrict do the heavy lifting. In you particular case, that query must probably be something like [Email1Address] = '[email protected]'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1