0

我正在尝试在 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

4

5 回答 5

1

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

于 2009-05-04T23:10:20.277 回答
1

做这种事情需要很长时间,因为您必须从每个项目的交换存储中提取数据。

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

在其他过程中使用 CDO/RDO 在带外处理此信息。或者使用 MapiTables,因为这是获取属性的最快方法,但有一些注意事项,您可能在您的进程中做一些可以带入表格的事情。

兑换包装 - http://www.dimastr.com/redemption/mapitable.htm

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

于 2009-05-06T12:14:39.413 回答
0

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

任何类型的 UI 更新都非常昂贵;如果您要写出文本或增加进度条,最好谨慎行事。

于 2009-05-04T23:31:24.093 回答
0

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

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

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

于 2009-05-13T17:18:34.180 回答
0

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

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

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

因此,我做了以下事情:

我添加了第二个名为“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属性的次数越少越好!您可以通过使用 Restrict 和逻辑来进一步提高效率,以降低编译器必须循环遍历逻辑的次数。

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

于 2019-06-05T08:13:06.537 回答