C# MailSender и спать
Я пишу программу, которая отправляет электронную почту через класс SmtpClient. Я использую этот код:
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("mailSMTP.it");
mail.From = new MailAddress("address.it");
mail.Subject = "oggetto";
mail.IsBodyHtml = true;
string htmlBody = "someHTML";
mail.Body = htmlBody;
SmtpServer.Port = 25;
SmtpServer.EnableSsl = false;
foreach (string indirizzo in indirizzi)
{
mail.To.Clear();
mail.To.Add(indirizzo);
SmtpServer.Send(mail);
System.Threading.Thread.Sleep(3000);
}
MessageBox.Show("e-mail spedite!");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
но это работает, только если я пересекаю линию "Sleep". Зачем? Я думал, что это хорошая идея, чтобы отдохнуть во время этого процесса.
5 ответов
Учитывая, что есть исключение, при условии, что это по вызову Send
Я бы предложил не использовать повторно MailMessage
объект и создание нового на каждой итерации цикла. например:
//...
foreach (string indirizzo in indirizzi)
{
string htmlBody = "someHTML";
MailMessage mail = new MailMessage
{
From = new MailAddress("address.it"),
Subject = "oggetto",
IsBodyHtml = true,
Body = htmlBody,
};
mail.To.Clear();
mail.To.Add(indirizzo);
SmtpServer.Send(mail);
}
Если под "работами" вы подразумеваете MessageBox
появляется в разумные сроки... то причина в том, что Sleep
блокирует поток пользовательского интерфейса, пока все сообщения не будут отправлены. например, если вы попытаетесь отправить 10 сообщений, пользовательский интерфейс остановится на 30 секунд (3000 миллисекунд X 10).
На мой взгляд (и другие) вы должны стараться избегать Sleep практически любой ценой, чаще всего вы получаете приложение, которое ведет себя странно (например, поведение, которое вы описываете).
Я бы решил это с помощью таймера, который использует индекс, чтобы определить, какое из следующих писем будет отправлено. Что-то вроде этого:
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("mailSMTP.it");
mail.From = new MailAddress("address.it");
mail.Subject = "oggetto";
mail.IsBodyHtml = true;
string htmlBody = "someHTML";
mail.Body = htmlBody;
SmtpServer.Port = 25;
SmtpServer.EnableSsl = false;
var index = 0;
var timer = new System.Threading.Timer((callbackState) =>
{
mail.To.Clear();
mail.To.Add(indirizzi[index]);
SmtpServer.Send(mail);
index++;
if (index < indirizzi.Count)
timer.Change(3000, Timeout.Infinite);
else {
timer.Dispose();
Invoke(new Action(DisplayAllEmailsSentMessage));
}
}, timer, 3000, Timeout.Infinite);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Обратите внимание, что вам придется использовать Invoke для взаимодействия с Windows Forms любым способом, например, для отображения окна сообщения. Это потому, что обратный вызов Threading.Timer выполняется в собственном потоке.
Возможно, вы также сможете использовать Windows.Forms.Timer, но я редко использую его сам, поскольку он находится в пространстве имен Windows.Forms и, следовательно, подходит только для пользовательского интерфейса, написанного на Windows Forms.
Я думаю, что вы определяете новую тему для этого процесса, потому что если вы пишете System.Threading.Thread.Sleep(3000);
означает, что основной поток собирается спать на 3000 мс.
Итак, создайте вложенный поток для этого процесса, и после этого вы можете остановить / перевести ваш поток в поток.
Сервер Smtp разрывает ваше соединение из-за неактивности. Это наиболее вероятно, чтобы освободить ресурсы на сервере.
Из документации SmtpClient:
Соединение, установленное текущим экземпляром класса SmtpClient с SMTP-сервером, можно использовать повторно, если приложение желает отправить несколько сообщений на один и тот же SMTP-сервер. Это особенно полезно при использовании аутентификации или шифрования для установления соединения с SMTP-сервером. Процесс аутентификации и установления сеанса TLS может быть дорогостоящим процессом. Требование восстановления соединения для каждого сообщения при отправке большого количества сообщений на один и тот же SMTP-сервер может оказать существенное влияние на производительность.
В целом, другие респонденты правы, говоря, что вы не должны спать между отправкой. Сервер Smtp должен быть достаточно надежным, чтобы обрабатывать все электронные письма, которые вы можете отправить ему последовательно.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
class MailSender
{
public static int CreateMessageMdp(String destination,String mdp)
{
try
{
var client = new SmtpClient("smtp.domain.com", 587)
{
Credentials = new NetworkCredential("appgestionali@domain.com", "password"),
EnableSsl = true
};
DateTime localDate = DateTime.Now;
string body = "Suite à votre demande de mot de passe le " + localDate.ToString("F") + "\n on vous envoi votre mot de passe est :" + mdp;
client.Send("appgestionali@domain.com", destination, "Information", body);
}
catch (Exception ex)
{
MessageBox.Show(""+ ex.GetBaseException());
return -1;
}
return 0;
}
}
}