Почему я не получил все электронные письма после асинхронной отправки их в C #? - PullRequest
2 голосов
/ 08 декабря 2011

Я использую определенный класс для асинхронной отправки электронной почты. Вы можете найти оригинальный класс здесь .

Этот класс использует функцию делегата для отправки электронных писем:

public class Email
    {
        public bool SendEmail(MailMessage message)
        {
            try
            {
                SmtpClient smtpClient = new SmtpClient();
                smtpClient.Host = "smtp.gmail.com";
                smtpClient.Port = 587;
                smtpClient.EnableSsl = true;
                ...
                smtpClient.Send(message);
            }
            catch (Exception ex)
            {
                ErrorLogger.SaveLog(ex);
            }
            return true;
        }
        public delegate bool SendEmailDelegate(MailMessage message);

        public void GetResultsOnCallback(IAsyncResult ar)
        {
            SendEmailDelegate del = (SendEmailDelegate)((AsyncResult)ar).AsyncDelegate;
            try
            {
               bool result = del.EndInvoke(ar);
            }
            catch (Exception ex)
            {
                ErrorLogger.SaveLog(ex);
            }
        }

        public void SendEmailAsync(MailMessage message)
        {
            try
            {
                SendEmailDelegate dc = new SendEmailDelegate(this.SendEmail);
                AsyncCallback cb = new AsyncCallback(this.GetResultsOnCallback);
                IAsyncResult ar = dc.BeginInvoke(message, cb, null);
            }
            catch (Exception ex)
            {
                ErrorLogger.SaveLog(ex);
            }
        }
    }

Но на моем веб-сайте, разработанном в ASP.NET MVC 2, когда я пытаюсь отправить 96 писем, получено только несколько из них. Во время первого теста я получил 52 письма, а во второй - 57 писем.

У меня есть этот статический класс для вызова объекта отправляющей электронной почты

public static class EmailSender
{
  private static void SendEmail(MailMessage mail)
  {
     Email sender = new Email();
     sender.SendEmailAsync(mail);
  }

  public static void SendRevival(UserViewModel user){
    ...
    SendEmail(mailMessage);
  }
}

И я использовал это так:

foreach(UserViewModel user in users){
   EmailSender.SendRevival(user);
}

Нет ошибки ни из приложения, ни с сервера.

Кто-нибудь знает, что случилось?

Thx.

1 Ответ

1 голос
/ 08 декабря 2011

Вы смотрите ответ на ваш звонок на

sender.SendEmailAsync(mail);

чтобы узнать, действительно ли письмо было отправлено?

Я только что посмотрел на исходный код этого метода, и он делает это:

public bool SendEmailAsync(string toEmail, string toName)
        {
            try
            {
                SendEmailDelegate dc = new SendEmailDelegate(this.SendEmail);
                AsyncCallback cb = new AsyncCallback(this.GetResultsOnCallback);
                IAsyncResult ar = dc.BeginInvoke(toEmail, toName, cb, null);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

То есть код перехватывает любое выброшенное исключение и просто возвращает false. Не только это, но и в AsyncCallback он делает то же самое, то есть «ест» исключение, и вы никогда не узнаете о каких-либо исключениях.

Чтобы устранить вашу проблему, я бы использовал синхронный вызов SendEmail и изменил бы его код (в методе SendEmail) на NOT , чтобы перехватить Исключение, чтобы вызывающий (вы) знал, что произошло. например,

 private static void SendEmail(MailMessage mail)
 {
     Email sender = new Email();
     sender.SendEmail(mail);//modify this method as well!
 }
...