Outlook 2007 MailItem Info - медленно - PullRequest
0 голосов
/ 05 мая 2009

Я пытаюсь проанализировать электронную почту в Outlook 2007. Мне нужно максимально упростить ее и, похоже, возникли некоторые проблемы.

В основном это:

foreach( Folder fld in outllookApp.Session.Folders )
{
    foreach( MailItem mailItem in fld )
    {
        string body = mailItem.Body;
    }
}

и для 5000 электронных писем это занимает более 100 секунд. Мне не кажется, что это должно длиться так долго.

Если я добавлю:

string entry = mailItem.EntryID;

В конечном итоге это дополнительные 30 секунд.

Я выполняю все виды манипуляций со строками, включая регулярные выражения с этими строками и записываю их в базу данных, и тем не менее эти 2 строки занимают 50% моего времени выполнения.

Я использую Visual Studio 2008

Ответы [ 5 ]

1 голос
/ 06 мая 2009

Выполнение такого рода действий займет много времени, так как вам придется извлекать данные из хранилища обмена для каждого элемента.

Я думаю, что у вас есть несколько вариантов здесь ..

Обрабатывать эту информацию вне диапазона, используя CDO / RDO в другом процессе. Или же Используйте MapiTables, так как это самый быстрый способ получить свойства, хотя есть предостережения, и вы можете выполнять в процессе какие-то действия, которые можно перенести в таблицу.

Обертка погашения - http://www.dimastr.com/redemption/mapitable.htm

MAPI Таблицы http://msdn.microsoft.com/en-us/library/cc842056.aspx

1 голос
/ 05 мая 2009

Я не знаю, решит ли это вашу конкретную проблему, но последний пакет обновления для Office 2007 значительно улучшил производительность (улучшение) для Outlook с большим количеством сообщений.

0 голосов
/ 05 июня 2019

Я столкнулся с подобной ситуацией при попытке получить доступ к почте Outlook через VBA (в Excel). Однако в моем случае это было намного медленнее: 1 E-mail в секунду ! (Возможно, это было медленнее в моем, чем в вашем случае из-за того, что я реализовал его на VBA).

Во всяком случае, мне удалось улучшить скорость с помощью SetColumnns (например, https://docs.microsoft.com/en-us/office/vba/api/Outlook.Items.SetColumns)

Я знаю .. Я знаю .. Это работает только для нескольких свойств, таких как "Subject" и "ReceivedTime", а не для тела! Но подумайте еще раз: вы действительно хотите прочитать все ваши электронные письма? или это просто подмножество? может быть, на основе его строки «Тема» или «ReceivedTime»? Мое требование состояло в том, чтобы просто войти в тело письма, если его тема соответствует определенной строке!

Следовательно, я сделал следующее:

Я добавил второй объект Outlook.Items под названием myFilterItemCopyForBody и применил тот же фильтр, что и у других Outlook.Items. Итак, теперь у меня есть два «Outlook.Items»: «myFilterItem» и «myFilterItemCopyForBody» с одинаковыми элементами электронной почты, поскольку к обоим применяются одни и те же условия ограничения.

'myFilterItem' - для хранения только свойств 'Subject' и 'ReceivedTime' соответствующих писем (выполняется с помощью SetColumns) 'myFilterItemCopyForBody' - для хранения всех свойств почты (включая тело)

Теперь и myFilterItem, и myFilterItemCopyForBody сортируются с помощью ReceivedTime, чтобы располагать их в одном порядке.

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

Dim myFilterItem As Outlook.Items

Dim myItems As Outlook.Items
Set myItems = olFldr.Items

Set myFilterItemCopyForBody = myItems.Restrict("@SQL=""urn:schemas:httpmail:datereceived"" > '" & startTime & "' AND ""urn:schemas:httpmail:datereceived"" < '" & endTime & "'")
    Set myFilterItem = myItems.Restrict("@SQL=""urn:schemas:httpmail:datereceived"" > '" & startTime & "' AND ""urn:schemas:httpmail:datereceived"" < '" & endTime & "'")

myFilterItemCopyForBody.Sort ("ReceivedTime")
myFilterItem.Sort ("ReceivedTime")

myFilterItem.SetColumns ("Subject, ReceivedTime")

    For Each myItem1 In myFilterItem
        iCount = iCount + 1
        For Each myItem2 In myFilterItemCopyForBody
            jCount = jCount + 1
            If iCount = jCount Then
               'Display myItem2.Body if myItem1.Subject contain a specific string
                'MsgBox myItem2.Body
                jCount = 0
                Exit For
            End If
        Next myItem2
    Next myItem1

Примечание 1: Обратите внимание, что свойство Body доступно с помощью myItem2, соответствующего myFilterItemCopyForBody.

Примечание 2: Чем меньше раз компилятор входит в цикл для доступа к свойству body, тем лучше! Вы можете еще больше повысить эффективность, играя с Restrict и логикой, чтобы уменьшить количество циклов, которые компилятор должен циклически проходить по логике.

Надеюсь, это поможет, хотя это не что-то новое!

0 голосов
/ 13 мая 2009

У нас была точно такая же проблема, даже когда папки были локальными и сетевой задержки не было.

Мы получили 10-кратное ускорение, сохранив копию каждого письма в локальной таблице Sql Server CE, настроенной для необходимого поиска. Мы также использовали события обновления, чтобы убедиться, что локальная база данных остается синхронизированной с папками Outlook / Exchange.

Чтобы полностью устранить задержку пользователя, мы вынули поиск из цепочки Outlook и поместили его в собственную цепочку. Восприятие отставания было хуже, чем реальная задержка, как кажется.

0 голосов
/ 05 мая 2009

Вы просто читаете в этих строках в этом цикле, или вы читаете в строке, обрабатываете ее, затем переходите к следующей? Вы можете попробовать прочитать все сообщения в HashTable внутри вашего цикла, а затем обработать их после их загрузки - это может принести вам прибыль.

Любые обновления пользовательского интерфейса чрезвычайно дороги; если вы пишете текст или увеличиваете индикатор выполнения, лучше делать это экономно.

...