【问题标题】:SmtpClient - What is proper lifetime?SmtpClient - 什么是正确的生命周期?
【发布时间】:2018-07-10 18:09:27
【问题描述】:

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

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

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

什么是 SmtpClient 对象的正确生命周期? 我应该在每次发送批次时创建一个吗? 或者我应该在服务启动时创建一个并且从不丢弃它?

【问题讨论】:

    标签: c# .net email service


    【解决方案1】:

    您应该始终使用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:

    What are best practices for using SmtpClient, SendAsync and Dispose under .NET 4.0

    How to dispose objects having asynchronous methods called?

    相关阅读:

    MSDN SmtpClient

    Implementing Finalize and Dispose to clean up managed resources

    【讨论】:

    • 我不太同意“一有机会就尽快”的说法。我的申请中的“尽快”是什么?此外,创建 SmtpClient 需要时间,因为它需要建立安全连接。
    • 那是我疯狂编辑的剩余部分。没有什么可以阻止您使用一个客户端,特别是如果您完全控制电子邮件流,但是您可能会发现自己遇到无法发送电子邮件的例外情况,因为它仍在等待回复。如果限制数量,创建成本不会太高。如果您决定使用一个客户端,也许使用 BlockingCollection 和 Semaphore 可以实现这一目标
    • 我想我会在每批客户端上创建。它看起来更合乎逻辑,而不是每封电子邮件和每个应用程序一次。
    • 如果您在发送批量消息时添加描述 SmtpClient 最佳实践的小注释,我会接受您的回答。谢谢。
    • 嗨@Hooch 它是在主线程中处理的,还是您正在创建更多来执行此操作?
    【解决方案2】:

    从 .NET 4.0 开始,SmtpClient 将连接池化,因此您可以使用它一段时间。最好在发送完一批后将其丢弃。

    来自 MSDN:https://msdn.microsoft.com/en/us/library/system.net.mail.smtpclient(v=VS.100).aspx

    SmtpClient 类实现池化 SMTP 连接,这样它就可以避免为每条消息重新建立到同一服务器的连接的开销。应用程序可以重复使用相同的 SmtpClient 对象将许多不同的电子邮件发送到同一个 SMTP 服务器和许多不同的 SMTP 服务器。因此,无法确定应用程序何时使用 SmtpClient 对象完成并且应该对其进行清理。

    【讨论】:

      【解决方案3】:

      首先,在需要时使用任何对象是一种非常好的做法,除非您在整个应用程序中都需要它的实用程序。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        相关资源
        最近更新 更多