c# - 从收件箱下载附件时如何减少 EWS 调用?

标签 c# exchangewebservices ews-managed-api

我在 StackO 的帮助下编写了这个方法,但我一直找不到改进方法。

现在,我遍历 Office 365 收件箱中的每封邮件,遍历其附件集合,并将每个文件保存到磁盘(如果它是 Excel 工作簿)。这目前有效,但会导致大量调用 Exchange。收件箱的大小可能会变得非常大,因此需要很长时间才能运行,每次调用大约需要 0.5 秒。

如果我没记错的话,调用次数的比例为 (n/100) + 2n。

  • n 是收件箱中的消息数(每条消息调用 2 次)
  • 100 是 pageSize,因为我还没有见过比这更大的东西(每页调用一次)

注意:通常 (99.9999%) 每封邮件只有一个附件,但我为 CYA 目的添加了内部循环。可能有一些内存开销,但几乎没有比例因子。

我想知道是否有更好的方法来减少 Web 服务调用。有没有可以批量下载附件的EWS方法?我对 EWS 很陌生,所以我确定我在这里缺乏理解。 我想做的是减少 pageSizeLoad(path) 一批文件到磁盘,减少规模。

如有任何关于减少 EWS 调用的改进以下代码的建议,我们将不胜感激。

public void SaveAttachmentsFromInbox(string[] extensionFilter = null)
    {

        // Default to excel files
        extensionFilter = extensionFilter ?? new[] { ".xls", ".xlsx" };

        // Config for traversing inbox
        int offset = 0;
        int pageSize = 100;
        ItemView view = new ItemView(pageSize, offset, OffsetBasePoint.Beginning);
        view.PropertySet = PropertySet.FirstClassProperties;
        FindItemsResults<Item> findResults;

        // Loop through the inbox
        //   and save all attachments of the designated file types
        bool more = true;
        var fileCount = 0;
        while (more)
        {

            findResults = service.FindItems(WellKnownFolderName.Inbox, view);
            // Load each sheet's data into an Object
            foreach (var item in findResults.Items)
            {
                //get FirstClassProperties
                item.Load(view.PropertySet);

                string vendor = GetVendor(EmailMessage.Bind(service, item.Id));
                messageIds.Add(item.Id.ToString());

                // Save files to disk
                foreach (FileAttachment file in item.Attachments)
                {
                    string fileExtension = file.Name.Substring(file.Name.IndexOf('.'), file.Name.Length - file.Name.IndexOf('.'));

                    if (extensionFilter.Contains(fileExtension))
                    {
                        var fullPath = Path.Combine(path, file.Name);
                        attachmentInfo.Add(fullPath, vendor);

                        // Loads attachment and saves to disk
                        file.Load(fullPath);

                        fileCount++;
                        Console.Write("\rFiles received... {0}    ", fileCount);
                    }
                }
            }



            Console.WriteLine(); // Next line

            more = findResults.MoreAvailable;
            // Page through inbox if more messages remain
            if (more)
            {
                view.Offset += pageSize;
            }
        }
        Console.WriteLine(attachmentInfo.Count + " Excel Attachment Downloads successful.\n");
    }

最佳答案

除了使用 AQS 减少从服务器返回的记录集之外,您还应该使用批处理命令首先使用 LoadPropertiesForItems(替换每个项目代码中的绑定(bind))获取项目属性,然后您可以使用 GetAttachments 批处理附件下载(您需要确保使用 EWS Managed API 的 2.2 版)这意味着例如一批 100 个项目您进行一个 FindItems 调用、一个批处理 GetItem 调用和一个批处理 GetAttachment 调用而不是 1 * 100 * 100 如果您使用绑定(bind)和加载。例如像

         ItemView ivItemView = new ItemView(100);
        PropertySet flLevel = new PropertySet(BasePropertySet.IdOnly);
        ivItemView.PropertySet = flLevel;
        FindItemsResults<Item> faItems = service.FindItems(WellKnownFolderName.Inbox, "attachment:.xlsx OR attachment:xls", ivItemView);
        PropertySet slLevel = new PropertySet(BasePropertySet.FirstClassProperties);
        if (faItems.Items.Count > 0)
        {
            service.LoadPropertiesForItems(faItems, slLevel);
        }
        List<Attachment> atAttachments = new List<Attachment>();
        foreach (Item itItem in faItems.Items)
        {
            foreach (Attachment atAttachment in itItem.Attachments)
            {
                if (atAttachment is FileAttachment)
                {
                    string fileExtension = atAttachment.Name.Substring(atAttachment.Name.IndexOf('.'), atAttachment.Name.Length - atAttachment.Name.IndexOf('.'));
                    if (extensionFilter.Contains(fileExtension))
                    {
                        atAttachments.Add(atAttachment);

                    }
                }
            }
        }
        service.GetAttachments(atAttachments.ToArray(), BodyType.HTML,null);
        foreach (FileAttachment FileAttach in atAttachments)
        {
            Console.Write(FileAttach.Name);
            System.IO.File.WriteAllBytes("c:\\export\\" + FileAttach.Name, FileAttach.Content);
            //save off
        }

关于c# - 从收件箱下载附件时如何减少 EWS 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33898269/

相关文章:

c# - 需要将 C++ 转换为 C# 的帮助

c# - 在 EWS 中使用 StreamingSubscriptionConnection 时自动重新连接

c# - 使用 Exchange Web 服务 API 提取 Exchange 2007 公共(public)日历约会

c# - 如何使 C# 中的十进制数中的尾随零不被删除?

c# - 如何测量给定字体/大小的数字的像素宽度 (C#)

exchange-server - 什么导致 OnSubscriptionError 在 EWS API 的 StreamingSubscriptionConnection 中被触发?

python - 在exchangelib中访问 "Other Calendars"

c# - 使用 EWS 托管 API 2.2 获取原始发件人电子邮件地址

c# - Azure 存储模拟器 - 动态配置 CORS 会引发服务器身份验证错误

exchange-server - 从 Exchange 电子邮件地址获取自动发现 URL