Outlook, открывающий слишком много элементов, вызывает ошибку - PullRequest
1 голос
/ 26 декабря 2011

Моя цель - открыть общие календари для анализа и трассировки базы данных.

Суть в том, что мне удается открыть элементы, но через несколько сотен я получаю исключение.Это объясняет, что администратор (по соображениям безопасности) ограничил количество одновременно открытых элементов.

Я могу понять это, поэтому я попытался закрыть каждый элемент после прочтения.Но я все еще получаю ошибку.Проблема возникает, когда я читаю пользовательские свойства.

Вот пример моей программы:

Recipient recipient = mapiNamespace.CreateRecipient("John Doe");
if (recipient.Resolve())
{
    CalendarFolder = mapiNamespace.GetSharedDefaultFolder(recipient, OlDefaultFolders.olFolderCalendar);
    outlookCalendarItems = CalendarFolder.Items;
    outlookCalendarItems.IncludeRecurrences = false;
}
else
{
    Console.Write("Failed to open Calendar");
    return;
}

foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in outlookCalendarItems)
{
    Console.WriteLine(item.Subject + " -> " + item.Start.ToLongDateString());   //=> Ok, no problem
    UserProperty up = item.UserProperties.Find("Test");                   //=> Problem if too many items
    if( up!= null )
    {
        Console.Write("UserProperty Value: " + up.Value);
    }

    ((Microsoft.Office.Interop.Outlook._AppointmentItem)item).Close(OlInspectorClose.olDiscard);   //=> Problem if too many items
    Console.WriteLine();

}

Console.ReadKey();

Есть идеи, как правильно закрыть элементы?

Ответы [ 2 ]

2 голосов
/ 11 сентября 2013

В дополнение к использованию Masrhal.ReleaseCOMObject, вы также должны избегать использования многоточечной нотации (например, item.UserProperties.Find) - компилятор создаст неявную переменную для каждого "."- вы не можете явно освобождать такие переменные.

Во-вторых, не используйте цикл «foreach» - он сохраняет все ссылки на элементы коллекции до тех пор, пока цикл не завершится.Используйте цикл for.

В-третьих, циклически проходить по всем элементам в папке - это всегда ужасная идея - используйте MAPIFolder.GetTable.Или используйте MAPITable объект в погашении: http://www.dimastr.com/redemption/mapitable.htm

1 голос
/ 11 сентября 2013

Вот как я это сделал (на всякий случай, если кто-нибудь натолкнется на эту тему):

System.Runtime.InteropServices.Marshal.ReleaseComObject(_calendar_item);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
...