SmtpClient очень медленный - около 2 секунд, чтобы отправить одно очень маленькое письмо - PullRequest
7 голосов
/ 18 апреля 2011

Я использую SmtpClient для отправки простого электронного письма.

Письмо содержит около 25 символов (текст), поэтому оно маленькое.

Однако для отправки одного из них SmtpClient требуется около 2000 миллисекунд. Я не создаю SmtpClient для каждой отправки - он создается при запуске программы, поэтому единственное, что делается, это:

DateTime start = DateTime.Now;

MailMessage oMsg = new MailMessage();
// TODO: Replace with sender e-mail address.
oMsg.From = new MailAddress(settings._Username);
oMsg.To.Add(new MailAddress(emailEvent._ContactItemToUse.Data));
oMsg.Subject = emo._Subject;
oMsg.BodyEncoding = Encoding.UTF8;
oMsg.IsBodyHtml = emo._IsHtmlText;
oMsg.Body = emo._Text;
client.Send(oMsg);
TimeSpan timeWasted = DateTime.Now.Subtract(start); // between 1000-2000 ms

Это, конечно, очень плохо, и я не могу понять, почему. Ты можешь? =)

Ответы [ 6 ]

8 голосов
/ 22 апреля 2011

Я полагаю, что класс SmtpClient не использует одно и то же соединение для каждого отправленного письма (отредактируйте: теперь это возможно в .NET 4.0, см. Различия в документации для SmtpClient ). Открытие нового соединения стоит дорого, и это, вероятно, то, что требует времени. Есть коммерческие компоненты SMTP, которые делают и предлагают гораздо более высокую производительность. В зависимости от SMTP-сервера и размера почты, можно достичь чего-то вроде как минимум 50 писем в секунду.

Однако это может не быть проблемой для вас, если вы немного измените архитектуру. Что я делаю в своем приложении, так это то, что SmtpClient доставляет почту в папку, используя smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory и устанавливая PickupDirectoryLocation в требуемый каталог. Для этого вместо отправки почтовых сообщений по сети он записывает их в указанную папку как стандартные сообщения MIME (формат .eml).

Здесь вы можете использовать SMTP-сервер IIS или просто создать другой фоновый поток / процесс для использования созданных файлов .eml и доставки их получателям или другому SMTP-серверу.

Этот подход, я думаю, намного лучше, просто потому что:

  • Клиентский код, отправляющий письмо, никогда не должен ждать фактической отправки почты, что может занять значительное время, в зависимости от скорости соединения, задержки и т. Д.
  • Если отправленная почта не удалась, код клиента не будет затронут. Почту можно отправить в другое время в фоновом режиме.
  • Почтовая очередь постоянна, если приложение будет остановлено и запущено снова, почта в очереди не будет потеряна.
  • Проще для тестирования.

В качестве более простого подхода вы можете использовать SendAsync вместо Send, но он не дает всех непосредственных подходов, которые даст подход PickupDirectory.

3 голосов
/ 18 апреля 2011

Скорость класса SmtpClient в основном зависит от SMTP-сервера, к которому вы подключаетесь, и скорости вашего интернет-соединения. Лучший способ оптимизировать сквозной вывод, используя SmtpClient.SendAsync и создавая до 10 и более оптимизированных подключений к серверу smtp. В конце концов, это та же стратегия, что и все современные веб-браузеры для ускорения просмотра.

3 голосов
/ 18 апреля 2011

Несколько вещей приходят на ум.

Во-первых, некоторые сайты намеренно замедляют соединение, чтобы спамерам было менее выгодно отправлять почту на свои системы.Это называется Tarpitting.

Интересно, что почтовый сервер, который ваш сайт использует для рассылки, может даже включить это.(http://winzenz.blogspot.com/2005/12/enabling-smtp-tarpitting-in-windows.html)

Другие проблемы, которые могут вызывать проблемы, связаны с тем, что у принимающего почтового сервера есть короткий TTL для его настроек DNS, и / или на ВАШЕМ веб-сервере есть какой-то плохой (например, неисправный или перегруженный) DNSсерверы в настройке IP.

0 голосов
/ 22 января 2014

имел точно такую ​​же проблему.~ 2 секунды на электронную почту.

для нас это исправлено:

c:\windows\system32\set-receiveconnector "External - TLS Exempt" -MaxAcknowledgeDelay 0

Настройка свойств коннектора получения

0 голосов
/ 18 апреля 2011

Попробуйте telnetting и эмулируйте протокол для рассматриваемого smtp-сервера и посмотрите, какая команда на самом деле задерживает ваше общение.

Я предполагаю, что команда RCPT TO выполняет своего рода проверку, которая занимает некоторое время.

0 голосов
/ 18 апреля 2011

Может быть, это не твоя проблема. Чтобы отправить, сервер должен получить. В зависимости от вашего сервера, это может занять некоторое время. Вы тоже подтвердили эту часть?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...