11

我们正在使用带有c#的asp.net 3.5。我们必须制作一个强大的邮件模块。这个模块可以发送超过15000个收件人或DBMS中的所有记录。我想问一些事情。

1)我们有一个向单个收件人发送邮件的代码。我们将如何向多个收件人发送邮件。我尝试使用我们的代码通过“,”添加多个电子邮件 ID,但它只发送第一个电子邮件 ID。这里是代码示例

 public bool Mail(string to, string subject, string body)
        {
            try
            {

                MailMessage objEmail = new MailMessage();
                objEmail.To =to;
                objEmail.From = "Support@xyz.com";
                //objEmail.Priority =priority

                objEmail.Subject = subject;

                objEmail.Body = body;

                //enable the Html tag...

                objEmail.BodyFormat = MailFormat.Html;
                objEmail.Priority = MailPriority.High;

                SmtpMail.SmtpServer = "localhost";

                try
                {
                    SmtpMail.Send(objEmail);
                    return true;

                }
                catch(Exception ex)
                {
                    string error = ex.StackTrace;
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

2)一次发送邮件的最大限制是多少。意味着我们可以在包含电子邮件ID的字符串中分配多少值?

3)我们的代码的一个主要功能是单击按钮,所以如果我们有超过 15000 条记录,那么它是否能够全部发送到邮件,因为我们正在考虑的是该页面将有 60 秒的时间来呈现,因此它可能只发送那些 id 覆盖的邮件在 60 秒内。

让我们建议最好的方法是什么。

提前致谢。

4

3 回答 3

10

不要使用 System.Web.Mail。使用 System.Net.Mail。看到这个博客

System.Web.Mail 已弃用且不推荐使用。

您需要将工作传递到实际的邮件服务器/服务上。第三方是您的最佳选择。不要直接从 Web 应用程序代码发送电子邮件,因为请求超时、身份验证超时等最终会停止发送循环。此外,这个过程将锁定当前页面/会话,直到它完成/停止,当页面执行像这样的繁重任务时,我还经历过为所有访问者锁定的整个应用程序。

如果您想要的只是一个便宜的电子邮件服务器,您可以将电子邮件添加到队列中,并且服务器会快速浏览并发送它们,那么Amazon SES值得一看。如果您想要更多的用户管理和活动管理工具,那么MailChimpJangoMail可能是您的最佳选择。

Amazon SES 绝对是最便宜的,因为您只需按使用量付费。我平均一个月花4块钱。

所有这些都提供了您可以在代码中使用的 API。

另外:请确保您的收件人以某种方式请求或以其他方式期待这些电子邮件。发送垃圾邮件是非法的,处罚很严厉。

资源

还请检查以下问题:

于 2011-05-28T07:14:46.847 回答
3

除了 Chevex 回答:如果您向多个收件人发送电子邮件,请考虑使用密件抄送。如果您使用 TO 和 CC,每个收件人都会看到他们可能不喜欢的其他收件人的电子邮件地址。

如果您想推出自己的邮件发送模块而不是使用其中一种可用服务,请查看此问题,了解如何在 ASP.NET 中运行更长时间的后台任务的一些方法:在 ASP 中运行后台任务的最佳方式.Net 网络应用程序并获得反馈?

于 2011-05-28T07:32:28.423 回答
0

这是我的建议,它使用数据库来管理工作负载。

我将在这里使用 SQL Server 作为示例,因为这就是我一直在使用的自我。

您所做的是创建一个存储过程和/或指定一个表作为外发电子邮件的表。除了您需要发送电子邮件的表之外,该表还具有以下元数据。

SendDate
IsSent
ErrorCount
Priority

在某些时候,您将需要启动一个执行实际工作的线程或进程,但如何实现这一点很有趣。

使用 SQL Server,您可以编写如下查询:

DELCARE @now datetime; SET @now = GETDATE();

SELECT TOP (5) * 
FROM OutgoingEmail WITH (ROWLOCK, READPAST, UPDLOCK) 
WHERE SendDate < @now
    AND IsSent = 0 
    AND ErrorCount < 5
ORDER BY Priority
;

READPAST 只能在以 READ COMMITTED 或 REPEATABLE READ 隔离级别运行的事务中指定。您将在建立新连接时设置隔离级别。

现在会发生的是,当您使用SqlCommand对象创建DataReaderSQL Server 时会锁定那些行。没有其他实例能够获得它们。这意味着您现在有效地为外发电子邮件设置了工作队列。但是重要的是要记住,在进行处理时必须保持连接打开,否则锁定将被释放。

有几点需要注意。

  • 您获取一堆行并发送它们。如果您成功设置 IsSent 位
  • 如果您崩溃(在某处引发异常),您不会丢弃您引发 ErrorCount 的电子邮件。你不删除它,你只是增加计数。这很重要,因为如果电子邮件由于某种原因包含输入(而不是由网络连接问题引起),它可能会不断崩溃以发送客户端,这称为中毒,它将防止错误数据使您的发送客户端崩溃。因此,您应该忽略具有高ErrorCount
  • 您还可以清空滚动计划并向前SendDate推进,以免时不时地尝试相同的事情。
  • 瓶颈将是 SmtpClient 类,但根据您希望发送电子邮件的速度,您可以启动尽可能多的代理或线程来并行处理电子邮件。
  • 优先级将确保如果您需要发送高优先级电子邮件,完整的队列不会成为问题。例如,如果您想以这种方式发送所有电子邮件,则不会因为队列已满而延迟发送密码重置或注册电子邮件,只要它具有更高的优先级即可。

不过要注意的一件事是,当错误发生时原因未知,我看到偶尔的网络问题会导致电子邮件无法发送。这种方法通常会发生的情况是,电子邮件将在稍后网络连接或 SMTP 服务器重新联机时发送。您还可以拥有额外的元数据,以不向尝试重置其密码的用户发送超过一封电子邮件(只是因为某些未知原因,电子邮件现在没有被发送)。

最后一件事。您可能希望将表拆分为两个或三个相同的表。这样做的原因是,如果您想在一段时间内记录已发送的电子邮件,您不希望它们干扰您原本高性能的发送队列,因此您将它们移动到单独的表中,只是为了维护历史记录。错误处理也是一样的,如果电子邮件最终导致错误,您可能想要记录它,然后您可以通过将发送队列中的这些电子邮件移动到错误队列中来做到这一点。

于 2011-05-28T07:35:03.923 回答