代码之家  ›  专栏  ›  技术社区  ›  Sartheris Stormhammer

C#ImapX 2电子邮件检查代码似乎很慢

  •  1
  • Sartheris Stormhammer  · 技术社区  · 9 年前

    我正在使用 ImapX 2 让我的C#程序检查Gmail帐户中的电子邮件,但整个过程似乎花费了太多时间,我将在代码中解释:

    public static string checkForSubject() {
        ImapX.ImapClient client = new ImapX.ImapClient();
        client.Port = 993;
        client.UseSsl = true;
        client.Host = "imap.gmail.com";
        if (client.Connect()) {
            client.Login(Constants.EMAIL_SENDER, Constants.EMAIL_SENDER_PASSWORD);
            var messages = client.Folders.Inbox.Search("ALL"); // THIS LINE takes like 5-10 seconds to complete
            foreach (var item in messages) {
                if (item.Subject.StartsWith("HELLO_")) {
                    string s = item.Subject;
                    return s;
                }
            }
        }
        return null;
    }
    

    我的代码是否有问题,或者IMAP访问是否正常?

    2 回复  |  直到 9 年前
        1
  •  3
  •   jstedfast    9 年前

    嗯,您需要文件夹中所有邮件的UID或索引。如果文件夹中有大量邮件,并且IMAP服务器不支持ESEARCH扩展(和/或ImapX不利用ESEARCH的扩展),那么服务器将发送回一堵巨大的文本墙,可能需要很长时间才能传输。

    我所指的文本墙看起来像这样:

    * SEARCH 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 9999 10000
    

    每条消息都有一个号码。

    使用ESEARCH,您将获得:

    * ESEARCH 1:10000
    

    但这有点离题,因为看起来ImapX将下载所有匹配的消息,在您的情况下,这是文件夹中的所有消息。

    您的搜索效率也极低。如果您只希望邮件以 "HELLO_" ,您可以改为:

    var messages = client.Folders.Inbox.Search("SUBJECT HELLO_");
    foreach (var item in messages) {
        if (item.Subject.StartsWith("HELLO_")) {
            string s = item.Subject;
            return s;
        }
    }
    

    您仍然必须保留item.Subject.StartsWith()检查,因为IMAP无法检查字符串是否以字符串开头或结尾,它只是执行“包含”类型搜索。

    但是这个搜索查询将返回更少的匹配项,这意味着ImapX将下载更少的消息,这意味意味着它应该更快。

    不幸的是,对于你正在做的事情来说,它仍然非常低效,因为你所关心的只是主题字符串,而不是整个消息。

    我对ImapX不够熟悉,无法使其更高效,但如果您使用 MailKit 例如,您可以这样做:

    client.Inbox.Open (FolderAccess.ReadOnly);
    var uids = client.Inbox.Search (SearchQuery.SubjectContains ("HELLO_"));
    if (uids.Count > 0) {
        var summaries = client.Inbox.Fetch (uids, MessageSummaryItems.Envelope);
        foreach (var summary in summaries) {
            if (summary.Envelope.Subject.StartsWith ("HELLO_"))
                return summary.Envelope.Subject;
        }
    }
    

    希望这会有所帮助。

        2
  •  2
  •   Jan Fischer    8 年前

    通过限制电子邮件的下载部分,可以稍微提高性能。

    client.Folders.Inbox.Search("SUBJECT HELLO_", ImapX.Enums.MessageFetchMode.Minimal);
    

    只有主题和标题将被下载。

    推荐文章