У меня есть инструмент для рассылки новостей, который я пытаюсь настроить как фоновый процесс для отправки электронных писем. Приведенный ниже код работает без каких-либо проблем, но у меня проблема в том, что он медленный.
Если есть 50 электронных писем для отправки, это может быть очень медленным для конечного пользователя, так как они должны смотреть на экран в течение 1 минуты 30 секунд. Это становится большей проблемой для меня, если клиент отправляет электронное письмо большей группе людей.
Причина, по которой я отправляю каждое письмо в отдельности, в связи с отправкой 1 и bcc'ing списка электронной почты, заключается в том, что каждое электронное письмо содержит определенный конкретный контент для каждого пользователя - например, коды ссылок для отказа от подписки, персональное имя в начале письма и т. Д.
Я ищу решение, в котором я могу позволить пользователю щелкнуть по кнопке и заставить .net запускать отправляющую часть электронной почты в фоновом режиме, пока пользователь переднего плана переносится на страницу, сообщающую, что его электронная почта отправляется. В идеале, все это должно занимать не больше, чем обычная обратная передача, а не текущие несколько минут.
Есть мысли о том, как лучше всего этого добиться?
Спасибо за вашу помощь,
Рич
if (Page.IsPostBack)
{
if (JustMeButton.Checked)
{
SendMail("emailme@address", EmailTemplate);
}
if (EveryoneButton.Checked)
{
//setup background process
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
//bring user to next screen and display message
Response.Redirect("emailSendingMessageScreen.aspx");
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
DataTable emailTable = (DataTable)Session["emailTable"];
foreach (DataRow row in emailTable.Rows)
{
SendMail(row["email"], row["name"], EmailTemplate);
}
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!(e.Error == null))
{
SendMail("admin@address", "Error sending <br><br>" + e.Error.Message);
}
else
{
SendMail("admin@address", "emails sent successfully.");
}
//clear out the sessions created for sending this email
Session.Remove("emailTable");
}
private void SendMail(string email, string emailMessage)
{
MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress("from@address");
mailMessage.To.Add(new MailAddress(email));
mailMessage.Subject = Server.HtmlEncode(EmailSubject.Text.Trim());
mailMessage.Body = emailMessage;
mailMessage.IsBodyHtml = true;
SmtpClient smtpClient = new SmtpClient();
Object userState = mailMessage;
smtpClient.SendCompleted += new SendCompletedEventHandler(smtpClient_SendCompleted);
smtpClient.Timeout = 10000;
try
{
smtpClient.SendAsync(mailMessage, userState);
}
catch (SmtpException smtpExc)
{
MailMessageTxt.Text += "Error Code: " + smtpExc.StatusCode;
MailMessageTxt.Visible = true;
}
catch (Exception ex)
{
MailMessageTxt.Text += "Error is: " + ex;
MailMessageTxt.Visible = true;
}
}
void smtpClient_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
MailMessage mailMessage = e.UserState as MailMessage;
if (e.Error != null)
{
MailMessageTxt.Text = "Error occured, info=" + e.Error.Message;
MailMessageTxt.Visible = true;
}
}