【问题标题】:How to get a list of UIDs in reverse order with MailKit?如何使用 MailKit 以相反的顺序获取 UID 列表?
【发布时间】:2015-05-20 22:31:02
【问题描述】:

我想使用 MailKit 从收件箱中获取最新的 100 个 UID。我正在访问一个似乎不支持 SORT 扩展的 Gmail 邮箱,因此我无法使用 OrderBy。

这是我的代码。问题是它似乎检索了最旧的 100 封电子邮件,而不是最新的电子邮件(这是我希望它工作的方式)。有没有办法做到这一点?

选项 A - 看起来很有希望只获得 100 个最旧的电子邮件 UID,我想要 100 个最新的:

            imap.Inbox.Open(FolderAccess.ReadOnly);
            var orderBy = new [] { OrderBy.ReverseArrival };
            var items = imap.Inbox.Fetch(0, limit, MessageSummaryItems.UniqueId);

选项 B - 按日期顺序获取所有个 UID(但无论如何都不适用于 Gmail):

            imap.Inbox.Open(FolderAccess.ReadOnly);
            var orderBy = new [] { OrderBy.ReverseArrival };
            SearchQuery query = SearchQuery.All;
            var items = imap.Inbox.Search(query, orderBy);

IMAP 服务器不支持 SORT 扩展。

原因是为了快速扫描邮箱以提高对用户的响应能力。

【问题讨论】:

    标签: c# .net imap mailkit


    【解决方案1】:

    您在选项 A 中非常接近,您只是为前 2 个参数使用了错误的值。

    这就是你想要的:

    imap.Inbox.Open (FolderAccess.ReadOnly);
    if (imap.Inbox.Count > 0) {
        // fetch the UIDs of the newest 100 messages
        int index = Math.Max (imap.Inbox.Count - 100, 0);
        var items = imap.Inbox.Fetch (index, -1, MessageSummaryItems.UniqueId);
        ...
    }
    

    IMailFolder.Fetch (int, int, MessageSummaryItems) 的工作方式是第一个 int 参数是第一个消息索引,第二个参数是范围内的最后一个消息索引(-1 是一种特殊情况,仅表示“在文件夹”)。

    由于打开文件夹后,我们可以使用IMailFolder.Count 属性来获取文件夹中的邮件总数,我们可以使用它从末尾倒数以获取我们的起始索引。我们想要最后 100 个,所以我们可以做folder.Count - 100。我们使用Math.Max() 来确保如果文件夹中的邮件数量少于 100 条,我们不会得到负值。

    希望对您有所帮助。

    【讨论】:

    • 是的,这很棒,非常感谢。然后,我只需将结果颠倒过来,首先通过最新的电子邮件将它们按顺序排列。
    • 是的!忘记提了,但你显然想通了。 :-)
    • 感谢 jstedfast。顺便说一句,无论我只得到 1 还是 500,检索 UID 似乎都需要大约 5 秒。所有时间都在 IMAP 连接和身份验证中。所以获取 UID 非常快,但不是登录。这是您对速度的期望吗?
    • 这可能都取决于服务器。由于 DNS 查找、网络延迟、服务器负载等原因,打开连接可能需要一段时间。身份验证可能会故意减慢以降低暴力登录攻击的效率。获取 UID 可能非常快,因为服务器已经缓存了所有这些信息。
    • 对。它是gmail,所以很可能放慢速度以防止暴力攻击。 Google 喜欢鼓励人们使用 OAuth。
    【解决方案2】:

    如果你想单独下载每条消息,你可以做一些简单的事情。

    for (int i = inbox.Count-1; i > inbox.Count-101; i--)
    {
        var message = inbox.GetMessage(i);
        Console.WriteLine($"Subject: {message.Subject}");
    }
    

    如果您想在一个请求中接收所有内容,请尝试此操作。

    var lastHundredMessages = Enumerable.Range(inbox.Count - 100, 100).ToList();
    var messages = inbox.Fetch(lastHundredMessages, MailKit.MessageSummaryItems.UniqueId);
    foreach (var message in messages)
    {
        //To something here with this
    }
    

    【讨论】:

    • 这大约慢了一百倍,因为它发出一百个单消息请求而不是一百个消息请求,并且它下载每个附件以便顶部打印主题。
    • 你是对的。我会更新我的答案,让我知道你的想法
    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 2015-06-06
    • 2018-03-08
    • 2011-11-09
    相关资源
    最近更新 更多