2017-02-18 90 views
0

我有一个控制器发送一封电子邮件,并向我的ajax脚本返回“success”json响应。从控制器发送电子邮件时发生延迟

控制器看起来是这样的:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult EmailSend(string input1) 
    { 

     EmailSignup person = new EmailSignup { emailhasbeensent = false, Email = input1 }; 

     try 
     { 
      SmtpClient client = new SmtpClient("smtp.gmail.com", 587); 
      client.EnableSsl = true; 
      client.UseDefaultCredentials = false; 
      client.DeliveryMethod = SmtpDeliveryMethod.Network; 
      client.Credentials = new NetworkCredential("Email", "PW"); 

      MailMessage message = new MailMessage(); 
      message.From = new MailAddress("Email"); 
      message.To.Add(person.Email); 
      message.Subject = "Thank you for subscribing"; 
      message.Body = "You have now subscribed for our newsletter"; 
      message.IsBodyHtml = true; 
      client.Send(message); 
      person.emailhasbeensent = true; 
      return Json(new { status = "success" }); 
     } 

     catch (Exception ex) 
     { 
      return Json(new { status = "error" }); 
     } 
    } 

不幸的是,成功的响应之前延迟发送,这意味着其电子邮件正在进入排序的页面“空转”它接收到的前成功的回应。

有没有办法加快这个过程,以便立即发送响应? 如果没有,那么是否可以实施一个加载条,向用户显示“幕后”发生了什么?

回答

0

理想情况下,您应该考虑将时间消耗过程从UI线程移出并将此工作卸载到其他进程。例如,您可以将此信息(电子邮件所需的最小信息,您的案例中的toAddress)发送到队列,其中一些其他进程将从该队列读取并发送电子邮件。正确使用跨国队列确保了容错性。

另一种解决方案是将此工作交给ThreadPool中的另一个线程,以便您的UI线程无需等待代码完成执行。当其他线程无法成功完成操作时很难追踪!

private void SendEmail(string emailAddress) 
{ 
    // Your existing code to send email goes here 
    // Make sure you handle(LOG) exceptions 

} 

[HttpPost] 
public ActionResult EmailSend(string input1) 
{ 
    try 
    { 
     // Have another thread executes the SendEmail method 
     Task.Run(() => { SendEmail(input1); }); 
     return Json(new { status = "success" }); 
    } 
    catch (Exception ex) 
    { 
     //to do : LOG exceptions 
     return Json(new { status = "error" }); 
    } 
} 

现在,如果你不想做所有这些,您就可以在客户端的一些“加载”消息,以便用户知道有事情发生。下面的示例将按钮文本更改为“Please wait ...”。并禁用该按钮,以便用户不会再次单击它,直到我们收到来自我们的ajax调用的回复。

$(function() { 
    $("#emailSignup").click(function (e) { 
     e.preventDefault(); 
     var _this = $(this); 
     _this.text("Please wait...").attr("disabled", "disabled"); 

     $.ajax({ 
      type: 'POST', 
      url: "@Url.Action("EmailSend", "Home")", 
      data: { input1: "Some value" }, 
     }).done(function (res) { 
      if (res.status === "success") { 
       $("#MailFoot").hide(); 
       $("#ty").show(); 
      } 
      else { 
       _this.text("Please wait...").removeAttr("disabled"); 
       alert("Error sending email"); 
      } 
     }); 
    }); 
}) 

不是简单地更新按钮文本,你可以做任何你想做的!也许显示一个进度条?一个微调?只需在页面中保留一个微调图像(最初隐藏),并在ajax调用开始/结束时根据需要显示/隐藏/

+0

感谢您的回答!基本上,如果我将Sendemail代码移动到另一个方法,那么我的代码会不会失败,一旦生活就会失败?据我了解,我通过这样做防止了瓶颈? –