4

我刚刚编写了一些测试代码,查看 System.Net.Mail.SmtpClient 向自己发送相同的消息。

int numClients = 10;
List<SmtpClient> mailClients = new List<SmtpClient>();
for (int i = 0; i < numClients; i++) {
    mailClients.Add(new SmtpClient(smtpHost));
}

MailMessage msg = new MailMessage("myAddress@eg.com", "myAddress@eg.com", "test message", "" );
foreach (SmtpClient c in mailClients) {
    c.SendAsync(msg, null);
}

这一切都很好并且执行没有任何问题,除了我只收到'n - 1'消息。即,如果我发送 10 条消息,我的收件箱中只会收到 9 条消息。如果我发送 50 我只会收到 49 等等。

注意:如果我更改代码以使用阻止发送,那么我将始终收到正确数量的消息。例如

foreach (SmtpClient c in mailClients) {
    c.Send(msg);
} 

有任何想法吗?

4

1 回答 1

3

以下是一些可能有所帮助的观察结果:

  • 只创建一个 SmtpClient。
  • 而是创建多条消息。
  • SmtpClient 实现 IDisposable。. _
  • MailMessage 还实现了 IDisposable。

我怀疑您可能遇到了多个 SmtpClient 实例的错误/问题,这些实例都包装了同一个 SMTP 服务器。使用单个实例可以解决问题。

更新

根据 MSDN:

调用 SendAsync 后,您必须等待电子邮件传输完成,然后再尝试使用 Send 或 SendAsync 发送另一封电子邮件。

http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx

因此,鉴于您的情况,使用 SendAsync 而不是 Send 几乎没有任何好处。您的循环可能会踩到某些东西,因为您不等待之前的 SendAsync 完成。

这里有一些想法:

  • 如果您要发送一堆电子邮件,SendAsync 将执行与 Send 几乎相同的操作。只需使用发送。
  • 如果您需要并行发送,请使用生产者/消费者模式。一个(或多个)生产线程将内容转储到队列中发送,多个消费线程每个使用一个 SmtpClient 发送消息。使用 BlockingCollection 实现此模式非常简单。请参阅 MSDN http://msdn.microsoft.com/en-us/library/dd267312.aspx中的示例
  • 如果您使用足够多的线程,您的 SMTP 服务器将成为瓶颈。请注意何时超载。
于 2012-10-09T21:11:36.607 回答