2016-11-26 92 views
0

我正在开发一个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 
    } 

我的行动方法,你可以看到我试图发送电子邮件在后台的操作方法。我的代码成功发送电子邮件。但我相信它会冻结用户界面,因为它需要比应该的时间更长的时间。我测试了很多次。正常发送电子邮件没有区别。为什么它会冻结用户界面?我的代码没有在新的进程中发送后台电子邮件。

+2

运行异步并不意味着在后台运行,这不是它的工作原理。在mali任务完成之前,您的行为仍然不会返回。如果你想在后台发送邮件,你需要看另一种方法。例如,像Hangfire这样的启动后台任务的东西。 – DavidG

+0

哦。所以SendAsync不适用于在后台发送吗?所以,请我可以有一个链接,以获得最好的和简单的教程在后台发送电子邮件吗? –

+0

我有[简短的博客文章](https://contrivedexample.com/2016/11/05/upgrade-your-butler-to-async/)解释使用异步的最基本的情况。 – Crowcoder

回答

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服务)。

+0

谢谢你。感谢你的支持。我一直在阅读你的文章。文章不应该保证它可以使用异步任务完成。 –