【问题标题】:Exchange Web Services: Batching with FindItemsResult<Item>Exchange Web 服务:使用 FindItemsResult<Item> 进行批处理
【发布时间】:2010-09-30 17:09:41
【问题描述】:

我正在编写一个应用程序来处理电子邮件附件,使用 Exchange Web 服务。

我的问题区域的大致结构如下:

public static void Main()
{
    FindItemsResults<Item> findResults = FindItems();

    foreach (Item item in findResults)
    {
        DoSomethingWithItem(item);
    }
}

public static FindItemsResults<Item> FindItems()
{
            FindItemsResults<Item> findResults;

            ItemView view = new ItemView(10);    //batching 10 at a time
            view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Ascending);
            view.PropertySet = new PropertySet(
                BasePropertySet.IdOnly,
                ItemSchema.Subject,
                ItemSchema.DateTimeReceived);

            findResults = service.FindItems(
                WellKnownFolderName.Inbox,
                new SearchFilter.SearchFilterCollection(
                    LogicalOperator.Or,
                    new SearchFilter.ContainsSubstring(ItemSchema.Subject, Properties.Settings.Default.EmailSubject)),
                view);

            //return set of emails
            return findResults;
}

起初,这看起来不错 - 它完美地处理了我之前的测试示例。但是当我开始批量加载测试时,我意识到它只处理前 10 个项目,因为我指定了 10 个项目的批量大小 (ItemView view = new ItemView(10)),但我没有检查更多批次。

我本可以简单地增加批量大小,但后来快速谷歌,我找到了一个更好的例子:

public static FindItemsResults<Item> FindItems()
{
            FindItemsResults<Item> findResults;

            ItemView view = new ItemView(10, 0, OffsetBasePoint.Beginning); 
            view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Ascending);
            view.PropertySet = new PropertySet(
                BasePropertySet.IdOnly,
                ItemSchema.Subject,
                ItemSchema.DateTimeReceived);

            do
            {
                findResults = service.FindItems(
                    WellKnownFolderName.Inbox,
                    new SearchFilter.SearchFilterCollection(
                        LogicalOperator.Or,
                        new SearchFilter.ContainsSubstring(ItemSchema.Subject, Properties.Settings.Default.EmailSubject)),
                    view);

                //any more batches?
                if (findResults.NextPageOffset.HasValue)
                {
                    view.Offset = findResults.NextPageOffset.Value;
                }
            }
            while (findResults.MoreAvailable);

            return findResults;
}

这会循环处理尽可能多的电子邮件,但由于我还不明白的原因,foreach 循环现在只处理 findResults 中的第一项。

即使 findResults 包含多个项目 (findResults.Items.Count > 1),在我的第二个示例中,findResults.MoreAvailable = false。很公平,我之前已经遍历了批次,所以我正在查看最后一批的结尾是有道理的。

但是我如何重置 findResults 以便它处理整个批次?我尝试设置 findResults.MoreAvailable 但它是只读的......我错过了什么?

结论:

好的,所以我可以一次处理一个批次的项目,或者我可以将每个批次中的每个项目添加到一个列表中并稍后处理它们,就像我目前所做的那样。

他们之间并没有很多;我最初开始使用列表,但我会进一步考虑选择。

【问题讨论】:

    标签: c# exchangewebservices ews-managed-api


    【解决方案1】:

    在我看来,您的主要问题是您尝试定义一个返回 FindItemsResults&lt;Item&gt; 的函数。如果您使用结果配对,您将有 not one 这种类型的对象。而不是在检索每个新页面时,FindItemsResults&lt;Item&gt; 将被覆盖。以下示例显示来自Inbox 的所有项目的主题:

    ItemView view = new ItemView(10, 0, OffsetBasePoint.Beginning);
    view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
    view.PropertySet = new PropertySet(
        BasePropertySet.IdOnly,
        ItemSchema.Subject,
        ItemSchema.DateTimeReceived);
    
    // save the folder where we will make searching to do this one time
    Folder myInbox = Folder.Bind(service, WellKnownFolderName.Inbox);
    
    FindItemsResults<Item> findResults;
    
    do
    {
        findResults = myInbox.FindItems(
            new SearchFilter.ContainsSubstring(ItemSchema.Subject,
                    Properties.Settings.Default.EmailSubject)),
            view);
    
        foreach (Item item in findResults)
        {
            // Do something with the item.
            Console.WriteLine();
            if (item is EmailMessage)
            {
                EmailMessage em = item as EmailMessage;
                Console.WriteLine("Subject: \"{0}\"", em.Subject);
            }
            else if (item is MeetingRequest)
            {
                MeetingRequest mr = item as MeetingRequest;
                Console.WriteLine("Subject: \"{0}\"", mr.Subject);
            }
            else
            {
                // we can handle other item types
            }
        }
    
        //any more batches?
        if (findResults.NextPageOffset.HasValue)
        {
            view.Offset = findResults.NextPageOffset.Value;
        }
    }
    while (findResults.MoreAvailable);
    

    代码在控制台输出上显示主题。如果您想以另一种方式使用EmailMessageMeetingRequest,您应该修改代码对应。您还可以定义一个委托来处理找到的EmailMessageMeetingRequest,并在Console.WriteLine 的位置调用委托。如果您确实需要在某处相同的所有项目,那么您将必须创建一些像 List&lt;Item&gt; 这样的集合,在那里填写函数并返回而不是您目前所做的 FindItemsResults&lt;Item&gt;

    【讨论】:

      猜你喜欢
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2014-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多