Существует причина для повторного использования SmtpClient , это ограничивает количество подключений к SMTP-серверу. Я не могу создать новый класс SmtpClient класс для каждого потока, на котором строятся отчеты, иначе SMTP-сервер прекратит работу с ошибкой слишком большого числа соединений. Это решение, которое я придумал, когда не смог найти ответ здесь.
В итоге я использовал AutoResetEvent для синхронизации всего. Таким образом, я могу продолжать вызывать мой SendAsync в каждом потоке, но подождать, пока он обработает электронную почту, и использовать событие SendComplete , чтобы сбросить его и продолжить следующее.
Я установил событие автоматического сброса.
AutoResetEvent _autoResetEvent = new AutoResetEvent(true);
Я настраиваю общий SMTP-клиент, когда создается мой класс.
_smtpServer = new SmtpClient(_mailServer);
_smtpServer.Port = Convert.ToInt32(_mailPort);
_smtpServer.UseDefaultCredentials = false;
_smtpServer.Credentials = new System.Net.NetworkCredential(_mailUser, _mailPassword);
_smtpServer.EnableSsl = true;
_smtpServer.SendCompleted += SmtpServer_SendCompleted;
Затем, когда я вызываю асинхронную отправку, я жду, пока событие не очистится, а затем отправляю следующее.
_autoResetEvent.WaitOne();
_smtpServer.SendAsync(mail, mail);
mailWaiting++;
Я использую событие SMTPClient SendComplete для сброса AutoResetEvent и отправки следующего электронного письма.
private static void SmtpServer_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
MailMessage thisMesage = (MailMessage) e.UserState;
if (e.Error != null)
{
if (e.Error.InnerException != null)
{
writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: "
+ e.Error.Message + e.Error.InnerException.Message);
}
else
{
writeMessage("ERROR: Sending Mail: " + thisMesage.Subject + " Msg: " + e.Error.Message);
}
}
else
{
writeMessage("Success:" + thisMesage.Subject + " sent.");
}
if (_messagesPerConnection > 20)
{ /*Limit # of messages per connection,
After send then reset the SmtpClient before next thread release*/
_smtpServer = new SmtpClient(_mailServer);
_smtpServer.SendCompleted += SmtpServer_SendCompleted;
_smtpServer.Port = Convert.ToInt32(_mailPort);
_smtpServer.UseDefaultCredentials = false;
_smtpServer.Credentials = new NetworkCredential(_mailUser, _mailPassword);
_smtpServer.EnableSsl = true;
_messagesPerConnection = 0;
}
_autoResetEvent.Set();//Here is the event reset
mailWaiting--;
}