J'ai un outil de newsletter que j'essaye de configurer pour fonctionner comme un processus d'arrière-plan pour envoyer les emails. Le code ci-dessous fonctionne sans aucun problème mais le problème que j'ai est qu'il est lent.Définir un processus d'arrière-plan et permettre à l'utilisateur de continuer sans attendre
S'il y a 50 courriels à envoyer, cela peut être très lent pour l'utilisateur final car il doit regarder l'écran jusqu'à 1 min 30sec. Cela devient un plus gros problème pour moi si le client envoie un courriel à un plus grand groupe de personnes. La raison pour laquelle j'envoie chaque mail individuellement à l'envoi de 1 et à la liste de diffusion est que chaque email contient un contenu spécifique pour chaque utilisateur - comme des codes de lien de désabonnement, un nom de personne au début du mail, etc.
Je cherche une solution où je peux laisser l'utilisateur cliquer sur un bouton et avoir .net exécuter la partie d'email d'envoi en arrière-plan pendant que l'utilisateur final est amené à une page indiquant que leur email est envoyé . Idéalement, cela ne devrait pas prendre plus de temps qu'un postback régulier pour que tout cela se produise - pas les quelques minutes actuelles.
Des idées sur la meilleure façon d'y parvenir?
Merci pour votre aide, Rich
if (Page.IsPostBack)
{
if (JustMeButton.Checked)
{
SendMail("[email protected]", 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("[email protected]", "Error sending <br><br>" + e.Error.Message);
}
else
{
SendMail("[email protected]", "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("[email protected]");
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;
}
}
Bon exemple. Merci Chris :) –