【问题标题】:Sending Email Over SMTP Limit发送超过 SMTP 限制的电子邮件
【发布时间】:2016-03-25 06:48:46
【问题描述】:

我为一个大约有 100 到 120 名成员的小型组织维护网站。

每个月,我们都会发送一封电子邮件,通知我们的成员我们将在即将举行的会议中讨论的主题。

我正在尝试使用我们的网站为我们提供一种发送这些电子邮件的方式,但我们的 ASP 托管网站有定义的限制为每小时 50 封电子邮件

理论上,我想我可以在每次 SmtpClient.Send(MailMessage) 调用后使用 Thread.Sleep(60000) 让线程休眠 1 分钟,像这样:

public const int ONE_MINUTE = 60000;

public String SiteEmailAddress { get; set; }
public String SiteMailServer { get; set; }
public String SiteMailUserId { get; set; }
public String SiteMailPwd { get; set; }

public void BulkEmail(String emailMessage) {
    using (var msg = new MailMessage()) {
        msg.From = new MailAddress(SiteMailAddress);
        msg.Body = emailMessage;
        msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
        using (var server = new SmtpClient(SiteMailServer, 25)) {
            server.Credentials = new NetworkCredential(SiteMailUserId, SiteMailPwd);
            foreach (var person in Personnel.GetActiveMembers()) {
                var msgTo = person.PersonalEmail;
                if (!String.IsNullOrEmpty(msgTo)) {
                    msg.To.Clear();
                    msg.To.Add(new MailAddress(msgTo, person.FullName));
                    server.Send(msg);
                    System.Threading.Thread.Sleep(ONE_MINUTE);
                }
            }
        }
    }
}

这会导致我们的网站在运行时显示死机一个多小时,或者它可能会失败。

这样做的简单解决方案是什么?

【问题讨论】:

  • 主要电子邮件提供商采取的垃圾邮件预防措施很可能会将来自未知域的邮件标记为垃圾邮件。使用 3rd 方提供商进行群发邮件会更好
  • 如果在您的循环中清除msg.To,则添加您的所有收件人并发送一封电子邮件....

标签: c# asp.net .net email


【解决方案1】:

不要使用您的网络服务器发送电子邮件。

邮件发送 API 为您处理。这里不是推荐特定产品的地方,所以我不会。


如果您要通过网络服务器发送电子邮件,请不要在网络线程上执行此操作。将您的电子邮件发送状态存储在数据库中并一次发送一封,在单独的线程上进行,或使用单独的应用程序。

【讨论】:

  • 我很确定我的技术是错误的,但我从未尝试过或见过它做过。我欢迎链接到邮件发送 API,但它是一个非营利性的退伍军人组织。我已经为这个网站自掏腰包了。
  • SendGrid 和 Mailgun 都为每月发送多达 10000 封电子邮件的用户提供免费套餐。
  • 我注册了一个 Mailgun 帐户并更新了我的域设置。不过,它还需要几天时间才能生效。那么,我在托管域上的正常电子邮件是否仍然有效,还是 Mailgun 会接管所有这些?我没有看到通过 SendGrid 获得免费帐户的方法。
【解决方案2】:

根据您的情况,我会提出一些解决方案:
1-例如安排一个任务每1.2分钟运行一次,这个任务会调用email sender方法,不需要使用Sleep。
如何在asp.net网站中安排任务的例子:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
Best way to run scheduled tasks
http://hangfire.io/

2- 在 Windows 任务计划程序中手动或使用代码添加新任务(如果您的主机允许这样做),并使此任务调用您网站中发送电子邮件的页面。

3- 在一个单独的线程中创建一个单独的应用程序,它处理电子邮件发送过程而不影响您的主网站性能(这可能是一个 Windows 服务、控制台应用程序或普通的 Windows 应用程序)。

【讨论】:

    【解决方案3】:

    如果您决定从 Web 服务器发送电子邮件,则可以使用 ASP.NET 中的后台任务。 Scott Hanselman did a nice write up about it.。您可以让它一次处理 50 个,然后等待一个小时的剩余时间再继续,或者在每封电子邮件之间等待 72 秒,这样您每小时最多发送 50 个。

    【讨论】:

      【解决方案4】:

      我们使用 sendgrid 为我们的网站发送电子邮件,每月免费限制为 12,000 https://sendgrid.com/free 可能是更简单的选择?

      【讨论】:

      • 这听起来是个不错的计划,但这是针对非营利性退伍军人团体的。我现在是自掏腰包为网站付费。他们最基本的套餐是每月 10 美元,可接收 40,000 封电子邮件。这比我们能用的多 100 倍。
      • 如果 40,000 比您需要的多 100 倍,那么免费包中提供的 12,000 应该足以容纳您的 400 封电子邮件。
      【解决方案5】:

      首先创建后台线程并将其置于睡眠状态不会以任何方式杀死应用程序。它只会从线程池中获取线程并将其锁定直到操作完成,然后再将其处理掉。

      虽然这在高流量应用程序和有限线程池中可能会出现问题,在这些应用程序中必须同时处理多个请求。要考虑的另一件事是每次应用程序关闭时,如果运行,此任务会被取消。但是,如果这对您来说不是问题并且您想要一个简单的解决方案,那就是。

      我建议宁愿使用外部 API 来为您处理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-30
        • 2013-08-22
        • 1970-01-01
        • 1970-01-01
        • 2014-01-21
        • 2019-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多