3

我正在编写一个应用程序来处理电子邮件附件,使用 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 但它是只读的......我错过了什么?

结论:

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

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

4

1 回答 1

8

在我看来,您的主要问题是您尝试定义一个返回的函数FindItemsResults<Item>。如果您使用结果配对,您将没有一个此类对象。而不是在检索每个新页面时FindItemsResults<Item>都会被覆盖。以下示例显示来自 的所有项目的主题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);

代码在控制台输出上显示主题。如果你想使用EmailMessage或者MeetingRequest以其他方式你应该修改对应的代码。您还可以定义一个委托,它对找到的EmailMessage或执行某些操作并MeetingRequestConsole.WriteLine. 如果您确实需要在某处相同的所有项目,那么您将必须创建一些集合,例如List<Item>,填写函数并返回而不是FindItemsResults<Item>您当前所做的。

于 2010-10-02T21:39:42.167 回答