2017-08-30 32 views
2

我正在使用ASP.NET Web Form發送兩封電子郵件,一旦發送了兩封電子郵件,我正在從系統中刪除該文件。我的代碼使用異步/等待,並在控制檯應用程序中正常工作,但是當我將相同的代碼移到asp.net web窗體時,它發送電子郵件,但在Task.WaitAll(emailSender1,emailSender2)後沒有得到任何響應,因此,該文件不會被刪除,並且瀏覽器始終會看到正在加載。我試圖解決這個問題,但最終無法解決。我需要一些人幫助解決這個問題或任何可以完成的替代方法。我的代碼如下:總是在ASP.NET Web窗體的瀏覽器中使用async/await加載頁面

Default.aspx的

<%@ Page Language="C#" AutoEventWireup="true" Async="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %> 

<!DOCTYPE html> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:Button ID="btnSendEmail" runat="server" Text="Send Email" OnClick="btnSendEmail_Click" /> 
    </div> 
    </form> 
</body> 
</html> 

Default.aspx.cs背後

using System; 

namespace WebApplication1 
{ 
    public partial class Default : System.Web.UI.Page 
    { 
     private static string filePath = @"C:\Uploads\"; 
     protected void Page_Load(object sender, EventArgs e) 
     { 
     } 

     protected void btnSendEmail_Click(object sender, EventArgs e) 
     { 
      Sender mailSender = new Sender(); 
      mailSender.SendEmail("[email protected]", "[email protected]", "Async mail with attachment", "Async mail with attachment body goes here ...", filePath + "TestFile.txt"); 
      Response.Redirect("Succcess.apsx"); 
     } 
    } 
} 

Sender.cs代碼

using System.IO; 
using System.Net.Mail; 
using System.Text; 
using System.Threading.Tasks; 

namespace WebApplication1 
{ 
    public class Sender 
    { 
     public void SendEmail(string toEmail, string logMail, string title, string body, string attachmentPath) 
     { 
      var emailSender1 = SendEmailAsync(toEmail, title, body, attachmentPath); 
      var emailSender2 = SendEmailAsync(logMail, "Copy of " + title, body, attachmentPath); 

      Task.WaitAll(emailSender1, emailSender2); 

      // deleting file 
      File.Delete(attachmentPath); 
     } 
     public async Task SendEmailAsync(string toEmail, string title, string body, string attachmentPath) 
     { 
      // class to hold all values from the section system.net/mailSettings/smtp in app.config 
      MailConfiguration smtpSection = new MailConfiguration(); 
      using (MailMessage mailMsg = new MailMessage("<" + smtpSection.FromAddress + ">", toEmail)) 
      { 
       mailMsg.IsBodyHtml = true; 
       mailMsg.Subject = title; 
       mailMsg.SubjectEncoding = Encoding.UTF8; 
       mailMsg.Body = body; 
       mailMsg.BodyEncoding = Encoding.UTF8; 

       if (!string.IsNullOrWhiteSpace(attachmentPath) && File.Exists(attachmentPath)) 
       { 
        Attachment attachment = new Attachment(attachmentPath); 
        mailMsg.Attachments.Add(attachment); 
       } 
       using (SmtpClient smtpClient = new SmtpClient()) 
       { 
        smtpClient.Timeout = 1000000; 
        smtpClient.UseDefaultCredentials = false; 
        await smtpClient.SendMailAsync(mailMsg); 
       } 
      } 
     } 
    } 
} 

MailConfiguration.cs

public class MailConfiguration 
    { 
     private SmtpSection smtpSection = (ConfigurationManager.GetSection("system.net/mailSettings/smtp")) as SmtpSection; 

     public string ConfigurationFileName 
     { 
      get 
      { 
       try 
       { 
        return smtpSection.ElementInformation.Source; 
       } 
       catch (Exception) 
       { 
        return ""; 
       } 
      } 
     } 

     public string FromAddress 
     { 
      get 
      { 
       return smtpSection.From; 
      } 
     } 

     public string Host 
     { 
      get 
      { 
       return smtpSection.Network.Host; 
      } 
     } 

     public int Port 
     { 
      get 
      { 
       return smtpSection.Network.Port; 
      } 
     } 

     public int TimeOut 
     { 
      get 
      { 
       return 2000; 
      } 
     } 

     public override string ToString() 
     { 
      return "From: [" + FromAddress + "] Host: [" + Host + "] Port: [" + Port + "]"; 
     } 
    } 
+0

你已經嘗試過了_without_'異步= 「真」'在視圖? – benjrb

+0

是的,我做了,它給出了一個異常「InnerException = {」此時異步操作無法啓動。異步操作只能在異步處理程序或模塊內啓動,或者在頁生命週期中的某些事件期間啓動。如果執行頁面時發生此異常,請確保不包含「如果Anync =」true「 – Simant

+0

您真的不應該混用此異步代碼和非異步代碼,請執行所有異步或異步代碼。 – mason

回答

1

通過this article去後,我才知道,控制檯應用程序使用一個線程池的SynchronizationContext,而GUI或ASP.NET使用單塊-AT-A-時間的SynchronizationContext。這意味着造成死鎖的主要原因是因爲Task.WaitAll(emailSender1,emailSender2)。根據文章,我將這行代碼更改爲等待Task.WhenAll(emailSender1,emailSender2)。修正後的解決方案是:

Default.aspx.cs代碼隱藏

using System; 

namespace WebApplication1 
{ 
    public partial class Default : System.Web.UI.Page 
    { 
     private static string filePath = @"C:\Uploads\"; 
     protected void Page_Load(object sender, EventArgs e) 
     { 
     } 

     protected void btnSendEmail_Click(object sender, EventArgs e) 
     { 
      Sender mailSender = new Sender(); 
      mailSender.SendEmail("[email protected]", "[email protected]", "Async mail with attachment", "Async mail with attachment body goes here ...", filePath + "TestFile.txt"); 
      Response.Redirect("Success.aspx", false); 
     } 
    } 
} 

Sender.cs

using System; 
using System.IO; 
using System.Net.Mail; 
using System.Text; 
using System.Threading.Tasks; 

namespace WebApplication1 
{ 
    public class Sender 
    { 
     public void SendEmail(string toEmail, string logMail, string title, string body, string attachmentPath) 
     { 
      var result = ActualEmailSend(toEmail, logMail, title, body, attachmentPath); 
     } 

     public async Task ActualEmailSend(string toEmail, string logMail, string title, string body, string attachmentPath) 
     { 
      var emailSender1 = SendEmailAsync(toEmail, title, body, attachmentPath); 
      var emailSender2 = SendEmailAsync(logMail, "Copy of " + title, body, attachmentPath); 

      await Task.WhenAll(emailSender1, emailSender2); 

      if (!string.IsNullOrWhiteSpace(attachmentPath) && File.Exists(attachmentPath)) 
      { 
       File.Delete(attachmentPath); 
      } 
     } 
     public async Task SendEmailAsync(string toEmail, string title, string body, string attachmentPath) 
     { 
      try 
      { 
       // class to hold all values from the section system.net/mailSettings/smtp in app.config 
       MailConfiguration smtpSection = new MailConfiguration(); 
       using (MailMessage mailMsg = new MailMessage("<" + smtpSection.FromAddress + ">", toEmail)) 
       { 
        mailMsg.IsBodyHtml = true; 
        mailMsg.Subject = title; 
        mailMsg.SubjectEncoding = Encoding.UTF8; 
        mailMsg.Body = body; 
        mailMsg.BodyEncoding = Encoding.UTF8; 

        if (!string.IsNullOrWhiteSpace(attachmentPath) && File.Exists(attachmentPath)) 
        { 
         Attachment attachment = new Attachment(attachmentPath); 
         mailMsg.Attachments.Add(attachment); 
        } 
        using (SmtpClient smtpClient = new SmtpClient()) 
        { 
         smtpClient.Timeout = 1000000; 
         smtpClient.UseDefaultCredentials = false; 
         await smtpClient.SendMailAsync(mailMsg); 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("SendEmail exception: " + ex); 
      } 
      finally 
      { 
       Console.WriteLine("SendEmail done"); 
      } 
     } 
    } 
} 
相關問題