MailKit: попытка реализовать клиент IMAP в ASP.NET Core для получения нового почтового события

Я пытаюсь реализовать клиент IMAP в своем веб-проекте ASP.NET Core, чтобы он мог работать в собственном потоке, всякий раз, когда приходит новое электронное письмо, событие MailRecieved запускается, и я получаю синтаксический анализ тела электронной почты и сохранение в БД.

Но проблема в том, что я должен сделать свой MailClient Keep-Alive, чтобы я мог продолжать слушать новые электронные письма, что не работает в моем случае. Я читал образец кода в документации MailKit, где они используют System.Timer, к сожалению, В ASP.NET нет таймера.

Вот код, который я использую: -

 public static async Task MailSubscribe(IMAPConnection connection)
    {
        try
        {
            using (var client = new ImapClient())
            {
                client.ServerCertificateValidationCallback = (s, c, h, e) => true;
                await client.ConnectAsync(connection.Host, connection.Port, connection.EnableSSL);
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                if (client.IsConnected)
                    client.Authenticate(connection.UserName, connection.Password);
                if (client.IsAuthenticated)
                {
                    var inbox = client.Inbox;
                    inbox.Open(FolderAccess.ReadOnly);
                    inbox.MessagesArrived += async (s, e) =>
                    {
                        using (var mailFetch = new ImapClient())
                        {
                            mailFetch.ServerCertificateValidationCallback = (g, c, h, k) => true;
                            await mailFetch.ConnectAsync(connection.Host, connection.Port, connection.EnableSSL);
                            mailFetch.AuthenticationMechanisms.Remove("XOAUTH2");
                            if (mailFetch.IsConnected)
                                mailFetch.Authenticate(connection.UserName, connection.Password);
                            if (mailFetch.IsAuthenticated)
                            {
                                mailFetch.Inbox.Open(FolderAccess.ReadOnly);
                                var mailIds = mailFetch.Inbox.Search(SearchQuery.NotSeen);
                                foreach (var id in mailIds)
                                {
                                    var mail = mailFetch.Inbox.GetMessage(id);
                                    var htmlDoc = new HtmlDocument();
                                    htmlDoc.LoadHtml(mail.HtmlBody);
                                    var context = htmlDoc.GetElementbyId("context")?.InnerText;
                                    if (context != null)
                                    {
                                        var entity = context;
                                    }
                                }
                            }
                        };
                    };
                }
                using (var done = new CancellationTokenSource())
                {
                    var task = client.IdleAsync(done.Token);
                    int timeout = client.Timeout;
                    while (true)
                    {
                        Thread.Sleep(10000);
                        if (client.IsIdle)
                        {
                            if (!client.Inbox.IsOpen)
                                client.Inbox.Open(FolderAccess.ReadOnly);
                           client.Idle(done.Token);
                        }
                    }
                    // done.Cancel();
                    // task.Wait();
                }
                //client.Disconnect(true);
            };
        }
        catch (Exception ex)
        {
            string exception = ex.Message;
            string innerexception = ex.InnerException.ToString();
        }
    }

person tech2avinash    schedule 24.07.2017    source источник
comment
вы можете поделиться своим примером кода? нужно учиться для моего классного проекта?   -  person Fuzed Mass    schedule 30.10.2017


Ответы (1)


Существует конструктор CancellationTokenSource, который принимает значение тайм-аута int, которое вы можете использовать. Я думаю, что это доступно для ASP.NET Core.

Если нет, попробуйте что-то вроде этого:

while (true) {
    if (!client.Inbox.IsOpen)
        client.Inbox.Open(FolderAccess.ReadOnly);
    var task = client.IdleAsync (done.Token);
    Thread.Sleep(10000);
    done.Cancel();
    task.Wait();
}
person jstedfast    schedule 25.07.2017
comment
Также можно сделать с помощью CancelAfter - person VMAtm; 29.07.2017
comment
Привет, @jstedfast, не могли бы вы рассказать подробнее? Я пытаюсь сделать это в IHostedService (BackgroundService). Примеры, которые вы предоставили на github, великолепны, но мне трудно связать их друг с другом. Извините за вопрос об арматуре, но я застрял. - person NIMROD MAINA; 21.05.2019