通过C#网页发送大量电子邮件的最佳方法是什么?

3
我有一个项目需要从网页发送1到2000封电子邮件。一个开源的错误跟踪器使用线程发送邮件,但是它充斥着错误。
所以我想知道是否有人有任何想法,如何创建一个程序,一次发送多达2000封电子邮件?
我的同事告诉我将其留作一个进程(正常例程一次发送一封电子邮件),因为处理所有电子邮件不会花费很长时间。这似乎不对,我想使用线程...也许我喜欢复杂的例程?
[额外内容] 我有类似以下的代码: foreach(string email in emailAddresses) { MailMessage mailMessage = new MailMessage(); mailMessage.To.Add(...) ... SmtpClient client = new SmtpClient(); client.Send(mailMessage); }

也许可以参考这个链接:http://stackoverflow.com/questions/1607178/background-task-with-an-asp-net-web-application 但是我在其他帖子中读到,一次性发送2000封邮件有些过多,而且有些SMTP服务器可能会认为你在垃圾邮件,你可能不仅仅会遇到后台任务的问题。 - Rup
1
如果您使用线程,您会创建多少个?肯定不是2000个。您仍然会有一个单独的线程处理大量电子邮件。此外,您拥有的线程越多,每个线程用于发送电子邮件(操作中的慢部分)的带宽就越少,从而导致性能与原始的简单(单线程)解决方案相当。 - Kirk Woll
你是正确的。这个想法是只用一个线程来处理邮件,这样我就可以将用户从网页中移开... - Rob
但我开始意识到发送如此多的电子邮件可能会有问题... - Rob
3
哈哈,一个充满 bug 的缺陷跟踪器的讽刺... :) - BBlake
是的,我知道...有漏洞的错误跟踪器...不过正在改进 :) - Rob
4个回答

5
使用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,但系统必须等待所有电子邮件发送完成才能继续。不过我需要理解你的第二段话,感谢你的建议 :) - Rob
我意识到我的回答有些混淆,所以我编辑了上面的回复。另外,由于你是新手,随意给你喜欢的回复点赞。 - makerofthings7
我理解你的意思了,现在我也明白了我的同事在说什么。再次感谢。 - Rob
最后,如果您要将相同的消息发送给多个收件人,则可以使用分发列表或将多个目标收件人附加到同一封邮件中。需要注意的是,如果您将所有电子邮件地址都放在“收件人”栏中发送,而不是抄送或密送,则每个收件人都可以看到其他人的电子邮件地址。 - Rob
好的。不过我仍然不确定使用密送是一个好主意,就像你所说的一样,我确信会有限制。基本上,这是一个文件存储库,它会通过电子邮件通知那些希望接收电子邮件的用户已经上传了文件到文件夹中。它还必须是个人化的,即在消息中包含用户的姓名。 - Rob
显示剩余5条评论

1

您可能不想在为http请求提供服务的线程上发送2000封电子邮件。提交请求的用户将等待服务器响应,直到电子邮件发送完成,而这会减少一个可用于处理其他用户请求的线程。如果有许多此类请求,它可能会拖慢服务器性能。

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

在asp.net应用程序中创建后台线程是另一种可能性,但这样你就会陷入以下情况之一:

  1. 您必须拥有自己的任务队列,与正常线程池使用的队列分开。
  2. 您的电子邮件任务正在与用于提供http请求的任务竞争,并有可能使其处于饥饿状态。

话虽如此,在部署方案(共享服务器、客户端部署)中,引入第二个进程是不可取的。然而,如果没有这些限制,我会选择“单独的进程”,因为如果集中于服务UI请求并将“履行”任务留给不同的服务,则更容易扩展您的网站。


非常感谢。看起来我需要认真思考如何管理这些电子邮件。我必须承认,我本来期望得到简单的答案,但现在证明我需要重新思考我的思维过程,因为时间和资源都很有限。再次感谢。 - Rob

0

我觉得2000可能需要很长时间(如果是网页而且用户在等待页面加载的话)。这取决于你的实现方式,但如果你经常这样做的话,你可能想要先创建一个已经存在的“电子邮件线程”。如果没有需要发送的电子邮件,那么该线程可以被挂起,不会占用任何资源。然后当需要发送电子邮件时,你可以将这些电子邮件填充到一个邮件队列中,并唤醒线程开始发送(如果它还没有在进行发送的话)。


0

如果您一次发送的邮件超过50封,您需要外包给一个为您完成此操作的服务。否则,您的邮件将最终被归类为垃圾邮件。


好的,我需要更多了解垃圾邮件。 - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接