2017-01-23 185 views
0

這是怎麼了,當我需要發送電子郵件給我的錯誤。但自從給我的錯誤是這樣的:發送郵件與SMTP SendAsync

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.

我已經積累了自MVC,並已使用類來跟蹤頁面的區域。我已經使用SendAsync的原因恰恰是它會快一點發送電子郵件等。

此錯誤只有當我試圖向用戶發送電子郵件發生。

public static void NewPassword(string mail, string name, string password) 
    { 
     MailDefinition oMailDefinition = new MailDefinition(); 
     oMailDefinition.BodyFileName = "~/MailList/emailskabelon/NewPassword.html"; 
     oMailDefinition.From = FromMail; 

     Dictionary<string, string> oReplacements = new Dictionary<string, string>(); 
     oReplacements.Add("<<navn>>", name); 
     oReplacements.Add("<<password>>", password); 

     System.Net.Mail.MailMessage oMailMessage = oMailDefinition.CreateMailMessage(mail, oReplacements, new LiteralControl()); 
     oMailMessage.Subject = NewpasswordTitle + WebsiteName; 
     oMailMessage.IsBodyHtml = true; 

     SmtpClient smtp = new SmtpClient(AzureApi); 
     System.Net.NetworkCredential netcred = new System.Net.NetworkCredential(AzureName, AzurePassword); 
     smtp.UseDefaultCredentials = false; 
     smtp.EnableSsl = true; 

     smtp.Credentials = netcred; 
     smtp.Port = Convert.ToInt32("25"); 
     smtp.DeliveryMethod = SmtpDeliveryMethod.Network; 

     using (var smtpClient = new SmtpClient()) 
     { 
      smtp.SendAsync(oMailMessage, null); 
     } 
    } 

我試着這樣做:

public static async NewPassword(string mail, string name, string password) 
     { 
      .... 
      using (var smtpClient = new SmtpClient()) 
      { 
       await smtp.SendAsync(oMailMessage, null); 
      } 

我已經在這裏看到:https://stackoverflow.com/a/35212320/7391454

+0

據我所知,異步方法需要返回類型 - 無論是否爲空。 – Takarii

回答

1

你的方法更改爲:

public async Task SendEmail(string toEmailAddress, string emailSubject, string emailMessage) 
{ 
var message = new MailMessage(); 
message.To.Add(toEmailAddress); 

message.Subject = emailSubject; 
message.Body = emailMessage; 

using (var smtpClient = new SmtpClient()) 
{ 
    await smtpClient.SendMailAsync(message); 
} 
} 

,並調用它像:

var task = SendEmail(toEmailAddress, emailSubject, emailMessage); 
var result = task.WaitAndUnwrapException(); 

看一看這裏Asynchronously sending Emails in C#? 這裏How to call asynchronous method from synchronous method in C#?

+0

給我一個錯誤:**方法'SendAsync'沒有超載需要1個參數** – Jasper

+0

你在哪裏使用SendAsynch? –

+0

U可以在這裏看到:[鏈接](http://imgur.com/a/6naaF) – Jasper

0

您也可以嘗試定義一個單獨的線程中的異步選項。 我相信你已經在你的頁面中插入了異步標籤。 如果一切正常,然後嘗試把你的代碼放在下面的塊中。

this.Page.RegisterAsyncTask(new PageAsyncTask(async ctoken => { 
     var result = await SomeOperationAsync(ctoken); 
     // result operations. 
})); 
+0

我理解的不僅僅是構建你已經完成的方式,以及如何將它插入到我的代碼中,與你寫的內容相比。 – Jasper

0

沒有真正回答你原來的問題,但只是想強調你更好關閉調用電子郵件發送代碼,而不保持調用線程等待。儘管您正在使用async/await,但從用戶角度來看,服務器完成發送電子郵件後,您仍然在瀏覽器中等待。這可能只有幾毫秒,但仍然最好由後臺工作人員來處理。

所以IMO,使用HostingEnvironment.QueueBackgroundWorkItem(x=> SendEmail());將是一個更好的辦法。

說了這麼多,你還是有,如果應用程序域在中間回收被終止異步任務的風險很小。但是,我認爲你的情況不太可能發生。即使發生這種情況,您也可以使用取消令牌並繞過它。