【问题标题】:What's the best way to send large amounts of email via C# Web page?通过 C# 网页发送大量电子邮件的最佳方式是什么?
【发布时间】:2011-05-21 03:06:56
【问题描述】:

我有一个项目的一部分,我需要从一个网页发送 1 到 2000 封电子邮件。一个开源错误跟踪器使用线程发送电子邮件,但它充满了错误。

所以只是想知道是否有人对我如何创建一个每次发送多达 2000 封电子邮件的程序有任何想法?

我的一位同事告诉我,将其保留为一个过程(一次发送一封电子邮件的正常例行程序),因为无论如何处理所有电子邮件都不会花费很长时间。似乎不对,我想使用线程……也许我喜欢复杂的例程?

[额外] 我有类似的东西: foreach(电子邮件地址中的字符串电子邮件) { MailMessage mailMessage = new MailMessage(); mailMessage.To.Add(...) ... SmtpClient 客户端 = 新 SmtpClient(); client.Send(mailMessage); }

【问题讨论】:

  • 也许见stackoverflow.com/questions/1607178/… 但是从我读过的其他线程 2000 一次很多,并且一些 SMTP 服务器可能会认为您正在发送垃圾邮件 - 您可能遇到的问题不仅仅是后台任务发送。
  • 如果你使用线程,你会创建多少? Surly 不是 2000。您仍然需要一个线程来处理大量电子邮件。此外,您拥有的线程越多,每个线程可用于发送电子邮件的带宽就越少(操作的缓慢部分),从而导致性能与原始直接(单线程)解决方案相当。
  • 你说得对。这个想法是一个线程只处理电子邮件,这样我就可以将用户从网页上移开......
  • 但是我开始发现发送这么多电子邮件可能会出现问题...
  • 嘿,一个充满错误的错误跟踪器的讽刺...... :)

标签: c# asp.net email


【解决方案1】:

我认为 2000 将需要很长时间(如果它是一个网页并且用户正在等待该页面)。这取决于您的实现,但您经常这样做,您可能希望拥有一个已经创建的“电子邮件线程”。如果没有要发送的电子邮件,则线程可以暂停并且不消耗任何资源。然后,当需要发送电子邮件时,您可以用这些电子邮件填充电子邮件队列并唤醒线程以开始发送(如果尚未这样做)。

【讨论】:

    【解决方案2】:

    使用 System.Net.Mail 发送消息;但是您应该使用 .NET 4 来避免任何连接问题,因为 Connect 网站上有一个错误会导致您的消息无法发送。

    出于三个原因不要使用线程:

    原因 1:MTA 用于处理消息重试,并且可以处理失败。您的代码可能不够健壮,无法处理此问题。 System.Net.Mail 无法立即执行此操作。

    原因 2: 如果您确实使用线程,您将压倒目标 SMTP 服务器并阻止您。大多数 Windows SMTP 中继都有超过 15 个(或 25 个?)并发连接的默认块。

    如果您使用的是 Exchange 2010 或 2007,那么如果您每分钟发送超过 x 条消息,就会激活一个限制功能。这是每个 MTA 的设置,需要根据您的情况进行调整。

    原因 3:最好的方法是拥有一个允许大容量并发连接的专用 IIS SMTP 服务器(或 Exchange...)。只需使用 Sys.Net.Mail 将传递任务交给邮件基础设施。邮件基础设施不需要太多。只要有一个 MTA 允许您进行中继,它就会代表您“智能主机”到互联网。

    更多关于如何设置 MTA 的问题可以@serverfault 回答。

    但是

    如果您从 ASP.NET 网页发送电子邮件,您可能需要使用线程……否则会阻塞 UI。除此之外,我认为不需要为电子邮件生成任务运行并发线程。

    最后,如果您将同一封邮件发送给多个收件人,您可以使用分发列表或将多个目标收件人附加到同一封邮件。

    【讨论】:

    • 好的。我还是使用了 Net Mail,但系统必须等待所有电子邮件发送完毕才能继续。我需要理解你的第二段,但感谢你的输入:)
    • 我意识到我很困惑,所以我编辑了上面的回复。另外,由于您是新人,请随时为您喜欢的回复点赞。
    • 我明白你在说什么,我现在明白我的同事在说什么。再次感谢。
    • 我使用的是 .NET 4,我们有一个专用的 IIS SMTP 服务器。
    • “最后,如果您将同一封邮件发送给多个收件人,您可以使用通讯组列表或将多个目标收件人附加到同一封邮件。”。需要在“收件人”中包含电子邮件,而不是抄送或密件,我确实在收件人中包含所有电子邮件地址,然后每个人都可以看到其他人的电子邮件地址......还是我误解了?
    【解决方案3】:

    如果您一次发送的邮件超过 50 个,则需要外包给为您执行此操作的服务。否则,您的邮件最终会进入人们的垃圾邮件文件夹。

    【讨论】:

    • 好的,我需要了解更多关于垃圾邮件的信息。
    【解决方案4】:

    您可能不想在为 http 请求提供服务的线程上发送 2000 封电子邮件。提交请求的用户将等待服务器响应,直到电子邮件发送为止,这减少了一个线程可用于处理来自其他用户的请求。如果您有很多这样的请求,它可能会降低服务器性能。

    相反,我会将请求发布到消息队列,并从队列中单独处理项目并发送电子邮件。

    在 asp.net 应用程序中创建后台线程是另一种可能性,但您最终会遇到以下情况:

    1. 您必须拥有自己的任务队列,与普通线程池使用的任务队列分开。
    2. 您的电子邮件任务正在与服务 http 请求的任务竞争,并且可能会饿死。

    话虽如此,在某些部署场景(共享服务器、客户部署)中,不希望引入第二个流程。但是,如果您没有这些限制,我会选择“单独的流程”,因为如果您的网站专注于提供 UI 请求并将“履行”任务留给不同的服务,那么它会更容易扩展您的网站。

    【讨论】:

    • 非常感谢。看起来我确实需要认真考虑如何管理这些电子邮件。我必须承认我期待简单的答案,但这证明我需要在有限的时间和资源下重新思考我的思维过程。再次感谢。
    猜你喜欢
    • 2011-07-02
    • 2010-09-08
    • 2020-09-28
    • 2013-02-12
    • 2012-09-20
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    相关资源
    最近更新 更多