Оптимальный способ отправки почты с SmtpClient? - PullRequest
5 голосов
/ 09 июня 2009

Я ищу хорошую производительность при отправке большого количества электронных писем.

Я слышал, что правильный способ сделать это - открыть соединение, отправить ~ 20 писем и закрыть соединение. И делай это снова и снова. Это правильно?

А как работает SmtpClient, открывает ли он соединение для своей жизни? (не IDisposable, поэтому не выглядит так) Или он открывает соединение для каждой отправляемой электронной почты? Или у него все время открыто соединение? Или у него есть какая-то магия, которая открывает и закрывает соединения, когда это уместно?

Я хотел бы знать, чтобы я знал, как мне следует инициировать SmtpClient. Как синглтон или только для части сообщений ...

1 Ответ

7 голосов
/ 09 июня 2009

Отправляет только одно MailMessage из соединения. На самом деле, он даже не закрывает соединение должным образом. Он отправляет почту, но затем не сообщает почтовому серверу, что он хочет выйти. Таким образом, он просто остается открытым, пока основной объединенный поток не решит закрыть сокет.

Вот внутренний код от Reflector:

...
        this.GetConnection();
        fileMailWriter = this.transport.SendMail((message.Sender != null) ? message.Sender : message.From, recipients, message.BuildDeliveryStatusNotificationString(), out exception);
        }
        catch (Exception exception2)
        {
            if (Logging.On)
            {
                Logging.Exception(Logging.Web, this, "Send", exception2);
            }
            if ((exception2 is SmtpFailedRecipientException) && !((SmtpFailedRecipientException) exception2).fatal)
            {
                throw;
            }
            this.Abort();
            if (this.timedOut)
            {
                throw new SmtpException(SR.GetString("net_timeout"));
            }
            if (((exception2 is SecurityException) || (exception2 is AuthenticationException)) || (exception2 is SmtpException))
            {
                throw;
            }
            throw new SmtpException(SR.GetString("SmtpSendMailFailure"), exception2);
        }

Кстати, здесь больше информации о том, что SmtpClient не выполняет команду QUIT. https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=146711&wa=wsignin1.0

Редактировать: просмотреть недействительную ссылку выше на web.archive.org

Обходное решение - установить SmtpClient.ServicePoint.MaxTimeout в 1. Это сократит сокет быстрее, однако на самом деле это не вызовет команду QUIT.

...