如何使用asp.net中的SendAsync()重新发送电子邮件

时间:2013-02-28 17:42:51

标签: asp.net system.net.mail

我正在使用SendAsync发送电子邮件。我使用异步的原因只是释放UI而不是发送多封电子邮件。

我创建了以下回调事件:

    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,而不是重用现有的,但说实话,我对.net很新,我不太清楚它的含义。

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分: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
}

我为你做的修复是构建一个所有失败地址的字符串,然后在后台工作完成后重新发送它们。欢呼声!!