我正在尝试在我的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();
}
}
答案 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();
}