0

我正在使用 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 还很陌生,我不太确定其中的含义。

任何意见,将不胜感激。

4

1 回答 1

2

在不延迟响应客户端(UI)的情况下异步发送电子邮件需要 .Net 中的 Backgroundworker。我在我的网站上实现了这一点, 并将与您分享课程源代码。

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
}

我为您所做的修复是构建所有失败地址的字符串,然后在后台工作人员完成工作后重新发送它们。干杯!!

于 2013-05-23T16:59:18.933 回答