2017-02-18 89 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代碼移動到另一個方法,那麼我的代碼會不會失敗,一旦生活就會失敗?據我瞭解,我通過這樣做防止了瓶頸? –