什么是在.NET 4.0下使用SmtpClient,SendAsync和Dispose的最佳实践

对于如何pipe理SmtpClient,我现在有些困惑,特别是在使用SendAsync进行调用时。 据推测,我不应该直到SendAsync完成调用Dispose。 但是我应该永远称它(例如,使用“使用”)。 这个场景是一个WCF服务,在打电话时定期邮寄电子邮件。 大部分的计算速度很快,但发送电子邮件可能需要一秒左右,所以asynchronous将是可取的。

我应该每次发送邮件时创build一个新的SmtpClient? 我应该为整个WCF创build一个吗? 帮帮我!

更新如果它有所作为,每个电子邮件总是为用户定制。 WCF托pipe在Azure上,Gmail用作邮件程序。

您应该始终尽可能地处理IDisposable实例。 在asynchronous呼叫的情况下,这是在消息发送后的callback。

 var message = new MailMessage("from", "to", "subject", "body")) var client = new SmtpClient("host"); client.SendCompleted += (s, e) => { client.Dispose(); message.Dispose(); }; client.SendAsync(message, null); 

有点讨厌SendAsync不接受callback。

最初的问题被要求用于.NET 4,但是如果.NET 4.5起作用,SmtpClient将实现asynchronous可用的方法SendMailAsync

因此,asynchronous发送邮件如下:

 public async Task SendEmail(string toEmailAddress, string emailSubject, string emailMessage) { var message = new MailMessage(); message.To.Add(toEmailAddress); message.Subject = emailSubject; message.Body = emailMessage; using (var smtpClient = new SmtpClient()) { await smtpClient.SendMailAsync(message); } } 

最好避免使用SendAsync方法。

一般而言,应尽快处理一次性使用物品; 在对象上实现IDisposable是为了传达这样一个事实,即所讨论的类包含昂贵的资源,这些资源应该被确定性地释放。 但是,如果创build这些资源非常昂贵并且需要构build大量这些对象,那么将一个实例保留在内存中并重用它可能会更好(性能明智)。 只有一个办法可以知道这是否有所作为:简介!

回复:处置和asynchronous:你不能明显using 。 相反,您通常将对象置于SendCompleted事件中:

 var smtpClient = new SmtpClient(); smtpClient.SendCompleted += (s, e) => smtpClient.Dispose(); smtpClient.SendAsync(...); 

好吧,我知道的老问题。 但是当我需要实现类似的东西的时候,我自己也偶然发现了这个问题。 我只是想分享一些代码。

我遍历几个SmtpClientasynchronous发送几个邮件。 我的解决scheme与TheCodeKing类似,但是我正在处理callback对象。 我也通过使用userToken传递MailMessage到SendCompleted事件中,以便我可以调用处理。 喜欢这个:

 foreach (Customer customer in Customers) { SmtpClient smtpClient = new SmtpClient(); //SmtpClient configuration out of this scope MailMessage message = new MailMessage(); //MailMessage configuration out of this scope smtpClient.SendCompleted += (s, e) => { SmtpClient callbackClient = s as SmtpClient; MailMessage callbackMailMessage = e.UserState as MailMessage; callbackClient.Dispose(); callbackMailMessage.Dispose(); }; smtpClient.SendAsync(message, message); } 

您可以看到为什么通过以下注释来处理SmtpClient尤为重要:

 public class SmtpClient : IDisposable // Summary: // Sends a QUIT message to the SMTP server, gracefully ends the TCP connection, // and releases all resources used by the current instance of the System.Net.Mail.SmtpClient // class. public void Dispose(); 

在我的情况下使用Gmail发送多个邮件而不处理客户端,我曾经得到:

消息:服务不可用,closures传输通道。 服务器响应是:4.7.0临时系统问题。 再试一次(WS)。 oo3sm17830090pdb.64 – gsmtp