SmtpClient - 合适的生命周期是什么?

13

我正在创建一个Windows服务,每5分钟发送一批电子邮件。

我希望每5分钟发送10-100封电子邮件的一批。这是极端情况。批次每5分钟发送一次,通常包含最多10封电子邮件。

我正在使用System.Net.Mail命名空间中的SmtpClient。

SmtpClient对象的适当生命周期是什么? 我应该每次发送一批邮件时都创建一个新的吗? 还是应该在服务启动时创建一个并永远不释放它?

3个回答

12

你应该始终使用using

using (var smtpClient = new SmtpClient())
{
    smtpClient.SendMail(message);
}

大多数情况下,您应该立即处理任何实现IDisposable的内容,一旦您完成使用它,但是您应该始终检查文档以确保。.NET 4.0中的SmtpClient类实现了IDisposable,因此请务必使用它!

引用MSDN的话:

SmtpClient类没有Finalize方法,因此应用程序必须调用Dispose来显式释放资源。

如果您发现自己正在执行异步相关任务,则可以为每个电子邮件创建一个新实例,以防止自己被阻塞。您可以使用以下内容:

var smtpClient = new SmtpClient();
smtpClient.SendCompleted += (s, e) => {
                           client.Dispose();
                           message.Dispose();
                        };
client.SendAsync(message, null);

批量发送电子邮件的最佳选项 - 根据请求

如上所述,您可以重复使用同一客户端。如果您将所有内容保留在同一个线程上,建议您只使用一个客户端。

MSDN说明:

SmtpClient类实现对SMTP连接进行汇集,以避免为了向同一服务器发送每个消息而重新建立连接的开销。应用程序可以重复使用同一SmtpClient对象将许多不同的电子邮件发送到同一SMTP服务器和许多不同的SMTP服务器。

然而,它继续说道:

…因此,没有办法确定应用程序何时完成使用SmtpClient对象并且应该进行清理。

因此,假设您在完成后处理了您的客户端,那么就没问题了。


下面链接了有关一些SMTP相关主题的讨论,我最近也问了同样的问题

Stackoverflow更多信息:

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

如何处置调用异步方法的对象?

相关阅读:

MSDN SmtpClient

实现Finalize和Dispose以清理托管资源


1
我并不完全同意“一有机会就”的部分,我的应用程序中的“一有机会就”是什么意思?此外,创建SmtpClient需要时间,因为它需要建立安全连接。 - Hooch
1
我认为每个批次创建一个客户端更加合理,比每封电子邮件和每个应用程序一个更加符合逻辑。 - Hooch
我在考虑每个批次创建一个线程。但是我不知道把每个消息都作为“异步”发送是否是一个好主意。我知道它可以工作,只是我没有经验,也不知道正确的方法。 - Hooch
@Hooch,我更新了我的答案。现在先使用一个线程。如果你以后想要使用异步代码,我已经提供了上面的代码。 - JEV
1
你应该在使用完实现了IDisposable接口的任何对象后立即进行处理。但这并不总是正确的,以HttpClient为例,它不应该被经常性地处理而是应该被持久化。 - Alex
显示剩余4条评论

5
自.NET 4.0以来,SmtpClient池化连接,因此您可能会在其上保持一段时间。最好在发送批处理后处理它。根据MSDN的说法:SmtpClient类实现池化SMTP连接,以避免为同一服务器的每个消息重新建立连接的开销。应用程序可以重复使用相同的SmtpClient对象将许多不同的电子邮件发送到同一个SMTP服务器和许多不同的SMTP服务器。因此,没有办法确定应用程序何时完成使用SmtpClient对象并且应该进行清理。 https://msdn.microsoft.com/en/us/library/system.net.mail.smtpclient(v=VS.100).aspx

0

首先,使用任何对象只要需要,直到您在整个应用程序中需要其实用性,这是非常好的实践。

其次,每次需要时都应创建SmtpClient的对象,并正确处理它,为此,请使用上面由Glitch100描述的using标记。

 using (var smtpClient = new SmtpClient())
 {
     smtpClient.SendMail(message);
 }

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