Outlook 2007 MailItem信息 - 慢

时间:2009-05-04 23:00:41

标签: c# visual-studio-2008 outlook outlook-2007

我正在尝试通过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秒。

我正在进行各种字符串操作,包括使用这些字符串的正则表达式并写入数据库,但这两行占用了我运行时的50%。

我正在使用Visual Studio 2008

5 个答案:

答案 0 :(得分:1)

我不知道这是否能解决您的具体问题,但最新的Office 2007 Service Pack为具有大量邮件的Outlook带来了显着的性能差异(改进)。

答案 1 :(得分:1)

这样做会花费很长时间,因为您必须从交换存储中为每个项目提取数据。

我认为你在这里有几个选择..

在其他一些过程中,在带外使用CDO / RDO处理此信息。 要么 使用MapiTables,因为这是获取属性的最快方法,虽然你可以在你的进程中处理可以带入表格的内容。

赎回包装 - http://www.dimastr.com/redemption/mapitable.htm

MAPI表http://msdn.microsoft.com/en-us/library/cc842056.aspx

答案 2 :(得分:0)

只是在这个循环中读取这些字符串,或者你是在读一个字符串,处理它,然后继续下一个?您可以尝试将所有消息读入循环内的HashTable,然后在加载后处理它们 - 它可能会为您带来一些收益。

任何类型的UI更新都非常昂贵;如果您正在写文本或递增进度条,最好这样做。

答案 3 :(得分:0)

即使文件夹是本地文件并且没有网络延迟,我们也遇到了完全相同的问题。

我们通过在本地Sql Server CE表中存储每封电子邮件的副本来获得10倍的加速,这些表针对我们需要的搜索进行了调整。我们还使用更新事件来确保本地数据库与Outlook / Exchange文件夹保持同步。

为了完全消除用户延迟,我们将搜索从Outlook线程中取出并将其放入自己的线程中。滞后的感觉比它看起来的实际延迟更糟糕。

答案 4 :(得分:0)

我在尝试通过VBA(在excel中)访问Outlook邮件时遇到了类似的情况。 但是,在我的情况下,它要慢得多:每秒1封电子邮件!(也许我的情况比您的情况要慢,因为我是在VBA上实现的。)< / p>

无论如何,我通过使用SetColumnns(例如https://docs.microsoft.com/en-us/office/vba/api/Outlook.Items.SetColumns)成功地设法提高了速度

我知道..我知道..这仅适用于一些属性,例如“主题”和“接收时间”,不适用于身体! 但是再想一想,您是否真的想通读所有电子邮件的正文?还是仅仅是一个子集?也许基于其“主题”行或“ ReceivedTime”? 我的要求是只是进入电子邮件正文,以防其主题与特定字符串匹配!

因此,我做了以下事情:

我添加了另一个名为“ myFilterItemCopyForBody”的“ Outlook.Items” obj,并在其他“ 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: 。请注意,使用与“ myFilterItemCopyForBody”相对应的“ myItem2”访问Body属性。

注2: :编译器进入循环以访问body属性的次数越少越好!您可以通过使用限制和逻辑来减少编译器必须循环遍历逻辑的次数,从而进一步提高效率。

希望这会有所帮助,即使这不是什么新鲜事!