发送背景电子邮件异步仍冻结UI
我正在开发一个ASP.NET MVC项目。我试图在不冻结用户界面的情况下在后台运行电子邮件。大多数文章都说现在可以使用.NET异步发送电子邮件来完成。我发送异步电子邮件,但它仍然冻结用户界面。我所做的是我注册输入电子邮件和密码,然后在后台发送验证电子邮件。我的发送电子邮件代码如下。发送背景电子邮件异步仍冻结UI
我有这样的接口。
public interface IMailHelper
{
Task SendEmailAsync(string to, string subject, string body, bool isHtml = true);
}
这是发送电子邮件的方法
public class MailHelper : IMailHelper
{
private string EmailAddress { get; set; }
private string EmailPassword { get; set; }
private int Port { get; set; }
private string Host { get; set; }
public MailHelper()
{
this.EmailAddress = AppConfig.SystemEmailAddress;
this.EmailPassword = AppConfig.SystemEmailPassword;
this.Port = AppConfig.SystemMailPort;
this.Host = AppConfig.SystemMailHost;
}
public async Task SendEmailAsync(string to, string subject, string body, bool isHtml = true)
{
var mail = new MailMessage();
mail.To.Add(to);
mail.From = new MailAddress(this.EmailAddress);
mail.Subject = subject;
mail.Body = body;
mail.IsBodyHtml = isHtml;
using (var smtp = new SmtpClient())
{
var credential = new NetworkCredential
{
UserName = this.EmailAddress,
Password = this.EmailPassword
};
smtp.UseDefaultCredentials = false;
smtp.Credentials = credential;
smtp.Host = this.Host;
smtp.Port = this.Port;
smtp.EnableSsl = true;
await smtp.SendMailAsync(mail);
}
}
}
接口实现正如你可以看到我送的异步电子邮件。
这是控制器
[HttpPost]
[AllowAnonymous]
//[AngularValidateAntiForgeryToken]
public async Task<JsonResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
//Do other stuffs here
await _mailHelper.SendEmailAsync(user.Email, AppConfig.AccountVerifyMailSubject, WebHelper.BuildAccountVerificationEmailBody(user.UserName, verificationUrl));
}
// Do other stuffs here
}
我的行动方法,你可以看到我试图发送电子邮件在后台的操作方法。我的代码成功发送电子邮件。但我相信它会冻结用户界面,因为它需要比应该的时间更长的时间。我测试了很多次。正常发送电子邮件没有区别。为什么它会冻结用户界面?我的代码没有在新的进程中发送后台电子邮件。
大多数文章说,现在可以使用.NET异步发送电子邮件完成。
这些文章都是错的,对不起。
我有一篇博客文章进入various implementations of ASP.NET background tasks。总之,如果你不在乎该邮件被偶尔会丢失,那么你可以只使用HostingEnvironment.QueueBackgroundWorkItem
:
[HttpPost]
[AllowAnonymous]
public async Task<JsonResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
...
HostingEnvironment.QueueUserWorkItem(_ =>
_mailHelper.SendEmailAsync(user.Email, AppConfig.AccountVerifyMailSubject, WebHelper.BuildAccountVerificationEmailBody(user.UserName, verificationUrl));
}
...
}
如果做护理该邮件不会丢失,那么你就必须到位他们在某种可靠的队列(Azure队列或MSMQ)中并且有独立的后台工作人员发送实际的电子邮件(Azure功能/ WebJob /工作者角色或Win32服务)。
谢谢你。感谢你的支持。我一直在阅读你的文章。文章不应该保证它可以使用异步任务完成。 –
运行异步并不意味着在后台运行,这不是它的工作原理。在mali任务完成之前,您的行为仍然不会返回。如果你想在后台发送邮件,你需要看另一种方法。例如,像Hangfire这样的启动后台任务的东西。 – DavidG
哦。所以SendAsync不适用于在后台发送吗?所以,请我可以有一个链接,以获得最好的和简单的教程在后台发送电子邮件吗? –
我有[简短的博客文章](https://contrivedexample.com/2016/11/05/upgrade-your-butler-to-async/)解释使用异步的最基本的情况。 – Crowcoder