在 ASP.NET C# 中异步发送电子邮件

本文关键字:电子邮件 异步 ASP NET | 更新日期: 2023-09-27 18:31:42

我想知道是否有办法在 asp.net c# 中异步发送电子邮件。我使用以下代码发送电子邮件:

 if (checkObavijest.Checked)
            {
                List<hsp_Kupci_Newsletter_Result> lista = ServisnaKlasa.KupciNewsletter();
                for (int i = 0; i < lista.Count; i++)
                {
                    MailMessage mail = new MailMessage();
                    mail.From = new MailAddress("*******");
                    mail.To.Add(lista[i].Email);
                    mail.Subject = "Subject";
                    mail.SubjectEncoding = Encoding.UTF8;
                    mail.BodyEncoding = Encoding.UTF8;
                    mail.IsBodyHtml = true;
                    mail.Priority = MailPriority.High;
                    mail.Body = "Some message";
                    SmtpClient smtpClient = new SmtpClient();
                    Object state = mail;
                    smtpClient.Credentials = new NetworkCredential("****@gmail.com", "****");
                    smtpClient.Port = 587;
                    smtpClient.Host = "smtp.gmail.com";
                    smtpClient.EnableSsl = true;
                    smtpClient.SendCompleted += new SendCompletedEventHandler(smtpClient_SendCompleted);
                    try
                    {
                        smtpClient.SendAsync(mail, state);
                    }
                    catch (Exception ex)
                    {
                    }
                }
 void smtpClient_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            MailMessage mail = e.UserState as MailMessage;
            if (!e.Cancelled && e.Error != null)
            {
                string poruka = "Emailovi poslani!";
                ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + poruka + "');", true);
            }
        }

但是当我勾选发送电子邮件的选项时,页面加载时间为 40 秒,然后在 40 秒后发送电子邮件。如您所见,我目前正在从数据库中取出 20-30 封电子邮件。我认为这是异步发送邮件的正确方法,但显然不是......如何将电子邮件推送到另一个线程,使其不会影响使用此页面的用户?有人可以帮助我解决这个问题吗?谢谢!

在 ASP.NET C# 中异步发送电子邮件

原因在 SmtpClient.SendAsync 上的 MSDN 文档中提到

调用 SendAsync 后,必须等待电子邮件传输到 在尝试使用"发送"发送另一封电子邮件之前完成 或发送异步。

您可以使用ThreadPool通过包装的方法调用来调用SendAsync。这将为您提供类似于即发即弃的场景。

像这样:

public void SendViaThread(System.Net.Mail.MailMessage message) {
    try {
        System.Threading.ThreadPool.QueueUserWorkItem(SendViaAsync, message);
    } catch (Exception ex) {
        throw;
    }
}
private void SendViaAsync(object stateObject) {
    System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();
    System.Net.Mail.MmailMessage message = (MmailMessage)stateObject;
    ...
    smtp.Credentials = new NetworkCredential("...");
    smtp.Port = 587;
    smtp.Host = "...";
    ...
    smtp.SendCompleted += new SendCompletedEventHandler(smtpClient_SendCompleted);
    ...
    smtp.Send(message);
}

你会在代码中调用SendViaThread(mail)。因此,您的循环现在变为:

for (int i = 0; i < lista.Count; i++) {
    MailMessage mail = new MailMessage();
    mail.From = new MailAddress("...");
    mail.To.Add(lista[i].Email);
    mail.Subject = "...";
    ...
    mail.Body = "...";
    SendViaThread(mail);
 }

如果您不想让主线程等待,请尝试将其扔到任务中。

Task.Factory.StartNew( () => {
  // do mail stuff here
});

请注意,每次生成任务时,它都会生成一个新的(或重用)您的系统创建的线程。 如果你发出 30 封电子邮件,你就有可能发出很多线程(系统也有一个可编程的上限)。 Task.Factory.StartNew是执行即发即弃过程的一种非常简单的方法。

http://msdn.microsoft.com/en-us/library/dd321439%28v=vs.110%29.aspx(在此示例中,代码还保留了Tasks的集合,如果您愿意管理它们,这很好 - 但实际上,如果您想触发并忘记,您只需要Task.Factory.StartNew(()=>{位。 只是要小心,因为您不希望孤立线程与您的内存使用量挂钩。