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 に答える