1

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 アクセスでは正常ですか?

4

2 に答える 2

3

フォルダ内のすべてのメッセージの 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

メッセージごとに 1 つの番号を取得します。

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;
    }
}

IMAP には文字列が文字列で始まるか文字列で終わるかをチェックする機能がないため、item.Subject.StartsWith() チェックを保持する必要があります。「含む」タイプの検索を行うだけです。

しかし、この検索クエリでは一致する結果がはるかに少なくなります。つまり、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;
    }
}

それが役立つことを願っています。

于 2015-06-25T21:37:21.713 に答える