2013-02-28 137 views
0

我正在使用SendAsync發送電子郵件。我使用異步的原因是簡單地釋放UI而不是發送多封電子郵件。如何在asp.net中使用SendAsync()重新發送電子郵件

我創建了以下回調事件:

static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) 
    { 
     var client = sender as SmtpClient; 
     var message = e.UserState as MailMessage; 

     if (e.Error.IsNotNull()) 
     { 
      if (e.Error is SmtpFailedRecipientException) 
      { 
       var status = ((SmtpFailedRecipientException)(e.Error)).StatusCode; 

       if (status == SmtpStatusCode.MailboxBusy || 
        status == SmtpStatusCode.MailboxUnavailable || 
        status == SmtpStatusCode.TransactionFailed) 
       { 
        // a new message! 
       } 
       else 
       { 
        // TODO: Log other uncaught recipient failures 
       } 
      } 
      else 
      { 
       // TODO: Log all other failure reasons 
      } 
     } 

     client.Dispose(); 
     message.Dispose(); 
    } 

正如你可以看到我試圖捕捉一些收件人失敗。如果我發現這樣的例外,我想嘗試重新發送電子郵件。

我正在努力解決如何安全地重新發送電子郵件。我正在考慮創建一個新的SmtpClient,而不是重複使用現有的SmtpClient,但說實話,我對.net相當陌生,並且我不太確定其含義。

任何意見,將不勝感激。

回答

2

異步發送電子郵件而不延遲響應客戶端(UI)需要.Net中的Backgroundworker。我在我的site上實現了這個功能,並將與您分享課程源代碼。

using System; 
using System.Collections.Generic; 
using System.Web; 
using System.ComponentModel; //Background worker namespace 
using System.Net.Mail; 


/// <summary> 
/// Summary description for ClassName 
/// </summary> 
/// 

public class postmail 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    string email1, subject1, message1, failedemails; 
    public postmail(string email, string subject, string message) 
    { 
      bw.WorkerReportsProgress = false; 
      bw.WorkerSupportsCancellation = false; 
      bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
      email1 = email; 
      subject1 = subject; 
      message1 = message; 
    } 

    public postmail() 
    { 
     // TODO: Complete member initialization 
    } 

    public void startsending() { 
     bw.RunWorkerAsync(); 
     HttpContext.Current.Response.Buffer = true; 
     HttpContext.Current.Response.Flush(); // send all buffered output to client 
     HttpContext.Current.Response.End(); 
    } 

    private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var finalemail = email1.Split(new[] { ',' }, StringSplitOptions.None); 
//loop through the email addresses and send individually 
     for (int c = 0; c < finalemail.Length; c++) { 
      try 
      { 

       MailMessage mailMessage = new MailMessage(); 

       // Sender Address 
       mailMessage.From = new MailAddress("emailaddress"); 

       // Recepient Address 
       mailMessage.To.Add(finalemail[c].ToString()); 

       // Subject 
       mailMessage.Subject = subject1.ToString(); 

       // Body 
       mailMessage.Body = message1.ToString(); 

       // format of mail message 
       mailMessage.IsBodyHtml = true; 

       // new instance of Smtpclient 
       SmtpClient mailSmtpClient = new SmtpClient("mail server"); 
       //mailSmtpClient.EnableSsl = true; 
       mailSmtpClient.Credentials = new System.Net.NetworkCredential("emailaddress", "password"); 
       // mail sent 
       Object userState = mailMessage; 
       mailSmtpClient.SendAsync(mailMessage, userState); 

      } 
      catch (Exception exc) 
      { 
      //fix for you 
      var ext = exc.ToString(); //catch exception for failed message 
      failedemails = failedemails + finalemail[c] + ","; //create a string of failed emails 

      }  
     } 

    } 
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
       //called when the background process is done working 
      if(failedemails != null){ 
       postmail(failedemails, subject1, message1); //resend the failed email 
       startsending(); 
      } 
    } 
} 

你的概念可能不是很準確像我一樣,但關鍵的方法是: 創建BackgroundWorker的事件處理程序。

BackgroundWorker bw = new BackgroundWorker(); 
bw.WorkerReportsProgress = false; 
      bw.WorkerSupportsCancellation = false; 
      bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 

bw.RunWorkerAsync(); 

    private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
      try 
      { 
       //Send your mail 

      } 
      catch (Exception exc) 
      { 
       //Catch exception here and call the resend method 
      }  
     } 

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    //do something after completion 
} 

我爲你做的修復是建立一個所有失敗地址的字符串,然後在backgroundworker完成工作後重新發送它們。乾杯!!

+0

如果失敗的郵件保持失敗.........代碼將無限運行。我建議你創建一個布爾變量來檢查重新發送,然後終止第二次重新發送。 – 2013-05-23 17:31:23

相關問題