2008-12-23 130 views
21

我正在尝试在.NET中使用SmtpClient编写通知服务(用于完全合法的非垃圾邮件目的)。最初,我只是通过每封邮件循环发送,但这很慢,我想提高速度。所以,我切换到使用“SendAsync”,但现在收到以下错误的第二个电话:为什么只能调用SmtpClient.SendAsync一次?

An asynchronous call is already in progress. 

我读这意味着MS瘫痪System.Net.Mail防止群发邮件。它是否正确?如果是这样,有没有更好的方式在.NET中做到这一点,并仍然能够记录每封电子邮件的结果(这对我们的客户来说很重要)。如果不是,为什么SendAsync只能被调用一次?

回答

35

按照documentation

调用SendAsync后,必须试图发送 使用发送或 SendAsync其他电子邮件消息之前等待 的E-mail发送到 完整。

因此,要同时发送多个邮件,您需要多个SmtpClient实例。

+0

是否有人已经实现了这种机制一次发送多个电子邮件?在smtp客户端类的顶部?听起来像是很多人遇到的问题......有点奇怪,没有人为它创建过一些框架。 – 2011-10-26 15:54:21

+3

@ItayLevin我没有看到需要尝试重用SmtpClient实例。 Darin熟练地解释了这一点,为什么不只是为每个电子邮件发送尝试分配每个实例。 – Roman 2012-04-23 17:54:53

+0

这是关于该主题的[良好帖子](http://www.codefrenzy.net/2012/01/30/how-asynchronous-is-smtpclient-sendasync/)。 – 2016-12-12 16:31:31

3

很显然,这不是企图阻止群发邮件。

原因是SmtpClient类不是线程安全的。如果要同时发送多个电子邮件,则必须生成一些工作线程(在.NET Framework中有几种方法可以实现这一点),并在每个线程中创建单独的SmtpClient实例。

1

每个SMTP客户端一次只能发送一个。如果您希望发送多个发送呼叫,请创建多个SMTP客户端。

HTH,

科尔比非洲

3

我想你误会XXXAsync类的方法。这些异步调用的目的是让程序继续运行,而不需要方法来完成处理并首先返回。然后,您可以通过订阅对象的XXXReceived事件来处理结果。

要同时发送多个邮件,您可以考虑使用更多Thread s。

2

正如其他人在这里注意到的,您一次只能发送一封电子邮件,但发送第一封邮件的方式是处理SmtpClient类的.SendCompleted事件,然后继续下一封电子邮件并发送。

如果您想同时发送多封电子邮件,正如其他人所说的那样,请使用多个SmtpClient对象。

6

您可能能够使用以下命令:

ThreadPool.QueueUserWorkItem(state => client.Send(msg)); 

这应该允许进行排队和发送,线程邮件变得可用。

相关问题