2016-05-23 65 views
1

我需要發送大約5000封電子郵件作爲我的網站用戶的電子郵件異步..問題是我不知道最好的方式發送它們異步..請幫我更新我的代碼,使其異步如何在ASP.NET中異步發送通訊(批量電子郵件)

我的代碼:

public string SendEmail() 
    { 


     foreach (var emailAddress in EmailList) 

     { 
      var message = new MailMessage("[email protected]", emailAddress); 

      message.Subject = "hi"; 
      SmtpClient client = new SmtpClient("smtp.gmail.com", 587); 
      client.Credentials = new NetworkCredential("[email protected]", "*****"); 
      client.EnableSsl = true; 
      client.Send(message); 
     } 
     return "done"; 
    } 

謝謝,露西

+0

由於[THIS](https://msdn.microsoft.com/de-de/library/x5x13z6h(v = vs.110).aspx)應該有一個異步函數文章 – Marius

+1

1)創建窗口服務器 2)安排它在2分鐘內執行 3)爲每封電子郵件創建線程。 這樣你可以異步發送電子郵件。 –

+0

在操作方法中使用異步/等待仍然強制用戶等待一切完成。您可以使用單一線程以「即燃即用」方式在後臺執行所有處理,而用戶可以執行其他操作(即使離開您的網站或關閉瀏覽器)。 –

回答

2

看看asyncawait關鍵字。

https://msdn.microsoft.com/en-us/library/mt674882.aspx

異步和等待關鍵字在C#中的異步編程的心臟。通過使用這兩個關鍵字,您可以使用.NET Framework或Windows運行時中的資源創建一個異步方法,就像創建同步方法一樣容易。通過使用async和await定義的異步方法稱爲異步方法。

MSDN解釋事物的語法方面。更大的擔憂是錯誤處理和可靠。將5000封電子郵件轉儲到列表中,然後點擊「發送」按鈕有點樂觀。這些電子郵件是否需要可靠地交付?如果發送其中的3000個,會發生什麼情況,並且網絡錯誤突然導致傳出郵件服務器暫時失去連接?當它重新開始工作時,你是否會重新發送所有5,000個?忘記過去的2000年?收件人是否會因爲重複而發瘋?或者根本沒有收到郵件?你如何解決錯誤?

我發現已經真的很好的模式(無論您是同步或異步發送),是產生信息和每個存儲在數據庫中的表,然後使用類似以下內容:

public void SendAllEmails() 
{ 
    var emails = SomeClass.GetAllUnsentEmails(); 

    foreach(Email message in Emails) 
    { 
     var success = SendEmail(message); 

     if (!success) 
     { 
      // Do you want to do something if it fails? 
     } 
    } 
} 

public bool SendEmail(Email message) 
{ 
    try 
    { 
     // 1. Send the email message 
     // 2. Update the "SentOn" date in the database 
     // 3. return true 
    } 
    catch(Exception ex) 
    { 
     SomeClass.CreateEmailErrorEntry(message, ex); // store error in a table or log 
     return false; 
    } 
} 
0

編輯:如果它正在採取行動的內部使用,你應該標記你的動作異步

public async Task<ActionResult> MyAction() 

一開始,沒有爲每個消息創建SmtpClient所以如下 也是這樣,應該異步發送的電子郵件,但等待他們全部被送到

public string SendEmail() 
    { 
     var tasks = new List<Task>(); 
     var client = new SmtpClient("smtp.gmail.com", 587); 
     client.Credentials = new NetworkCredential("[email protected]", "*****"); 
     client.EnableSsl = true; 
     foreach (var emailAddress in EmailList) 
     { 
      var message = new MailMessage("[email protected]", emailAddress); 
      message.Subject = "hi"; 
      tasks.Add(client.SendMailAsync(message)); 
     } 
     while(tasks.Count > 0) 
     { 
      var idx = Task.WaitAny(tasks.ToArray()); 
      tasks.RemoveAt(idx); 
     } 
     return "done"; 
    } 
+0

感謝您的幫助和時間....對於tasks.Add(client.SendAsync(message));它說參數1:不能從'void'轉換爲'System.Threading.Tasks。任務' – Lucia

+0

@Lucia修復了不正確的方法 – elibyy

+0

如果您想在退出while循環之前等待所有任務完成,您可能需要更改爲WaitAll。 – Asdfg