我正在开发一个ASP.NET MVC项目。我试图在后台运行时发送电子邮件而不冻结UI。大多数文章说现在可以用.NET异步发送电子邮件来完成。我发送异步电子邮件但它仍然冻结了用户界面。我正在做的是我注册输入电子邮件和密码,然后在后台发送验证邮件。我的发送电子邮件代码如下。
我有这样的界面。
public interface IMailHelper
{
Task SendEmailAsync(string to, string subject, string body, bool isHtml = true);
}
这是使用send-email方法的接口实现
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
}
正如您所看到的,我正在尝试在操作方法中在后台发送电子邮件。我的代码正在成功发送邮件。但我确信它会冻结用户界面,因为它需要的时间比它应该的要长。我测试了很多次。与正常发送电子邮件没什么不同为什么它会冻结用户界面?我的代码没有在新流程中发送后台电子邮件。
答案 0 :(得分:1)
现在大多数文章都说可以通过.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服务)。