来自 ASP.NET MVC 应用程序的 SMTP 邮件:数据库、队列文件夹还是异步?

cen*_*cru 2 c# asp.net email asp.net-mvc smtp

我们使用出色的 AuthSMTP 服务从 MVC 应用程序发送邮件。在升级到 .Net 4.5.1 之前,我们使用 SmtpMail.SendAsync 通过 IIS7 一次发送多封电子邮件。IIS7 设置为通过 AuthSMTP 中继邮件。

如今,.Net 中的异步代码似乎以不同的方式工作。我们回滚到 SmtpMail.Send,这降低了发送多封邮件的站点的速度。我们正在考虑以下选择。

  1. 重写代码以使用基于任务的异步模式。我们对此感到相当困惑,但如果这是一个不错的选择,我们可以坚持下去。

  2. 将电子邮件保存到数据库并使用作为计划任务触发的控制台应用程序发送。我们喜欢这个选项,因为它为我们提供了已发送电子邮件的存档。另一方面,我们需要访问数据库来存储电子邮件,这可能比要求 IIS 将外发邮件转储到队列文件夹慢。

  3. 让 IIS 将外发邮件保存到队列文件夹,并编写一个控制台应用程序来处理该队列。我们可以将每条消息存档在磁盘上,这是比存储在数据库中更糟糕的存档解决方案。

  4. 还有别的事。

谁能根据他们的经验告诉我们性能最佳的解决方案?

谢谢!

Jit*_*oli 5

在单独的线程中调用您的电子邮件函数,该函数将在后台发送电子邮件尝试此代码。

public static void SendEmail(string from, string[] to, string[] CC, string[] BCC, string subject, string body, SMTPSettings _smtp = null)
{
    Thread email = new Thread(delegate()
    {
        SendAsyncEmail(from, to, CC, BCC, subject, body, _smtp);
    });
    email.IsBackground = true;
    email.Start();
}

private static void SendAsyncEmail(string from, string[] to, string[] CC, string[] BCC, string subject, string body, SMTPSettings _smtp = null)
{
    try
    {
        MailMessage message = new MailMessage();
        SmtpClient client = new SmtpClient();       
        if (_smtp != null)
        {
            client.Host = _smtp.SMTPServer;
            client.Port = Convert.ToInt32(_smtp.SMTPPort);
            client.EnableSsl = _smtp.SMTPEnableSSL;
            client.Credentials = new System.Net.NetworkCredential(_smtp.SMTPUserEmail, SMTPPassword);
        }

        message.From = new MailAddress(from);
        message.Subject = subject;
        message.Body = body;
        message.IsBodyHtml = true;
        foreach (string t in to)
        {
            message.To.Add(new MailAddress(t));
        }

        if (CC != null)
            foreach (string c in CC)
            {
                message.CC.Add(new MailAddress(c));
            }

        if (BCC != null)
            foreach (string b in BCC)
            {
                message.Bcc.Add(new MailAddress(b));
            }
        client.Send(message);
    }
    catch (Exception ex)
    {
        ErrorLogRepository.LogErrorToDatabase(ex, null, null, "");
    }
}
Run Code Online (Sandbox Code Playgroud)