MailKit:尝试在ASP.NET Core中实现IMAP客户端以接收新邮件事件

时间:2017-07-24 06:32:59

标签: c# multithreading asp.net-core imap mailkit

我正在尝试在我的ASP.NET核心Web项目中实现IMAP客户端,以便它可以在自己的线程上运行,每当新的电子邮件到来时,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();
        }
    }

1 个答案:

答案 0 :(得分:3)

有一个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();
}