我在C#程序中使用ImapX 2来检查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访问正常?

最佳答案

好吧,您正在询问文件夹中所有消息的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;
    }
}


希望能有所帮助。

09-04 18:21