【问题标题】:Dispose Class. Do I need it?处置类。我需要吗?
【发布时间】:2013-04-10 02:26:59
【问题描述】:

我有以下邮件类:

public class Mail {
  public List<MailFile> Files { get; set; }
  public String Text { get; set; }
  // Other properties
}

public class MailFile {
  public Byte[] Data { get; set; }
  public String Mime { get; set; }
  public String Name { get; set; }
} // MailFile

Mail 包含一个文件列表,其中每个 MailFile 包含一个属性 Data,该属性包含 File 二进制数据。然后我使用 Mailer 发送电子邮件。

public class Mailer : IMailer {

  private SmtpClient _client;

  public Mailer() {
    _client = new SmtpClient { UseDefaultCredentials = true };
  } // Mailer

  public void Send(Mail mail) {

    using (MailMessage message = new MailMessage()) {
      message.Text = mail.Text);
      // Define other fields
      foreach (MailFile file in mail.Files)
        message.Attachments.Add(new Attachment(new MemoryStream(x.Data), x.Name, x.Mime)));

      _client.Send(message);

    };

  } // Send

  public void Dispose() {
    Dispose(true);
  } // Dispose

  protected virtual void Dispose(Boolean disposing) {
    if (disposing) {
      if (_client != null)
        _client.Dispose();
    }
  } // Dispose

} // Mailer

我将 MailMessage 包装在 using

  • 但在这种情况下,我是否需要处理邮件文件?
  • 我的 Mail 和 Mail 文件不是由 GC 管理和处置吗?
  • 也许我应该将 Mail 设为一次性并丢弃其 MailFiles?
  • 如果是,最好的方法是什么?

【问题讨论】:

  • 如果你需要在 GC 到达之前调用Dispose,你需要一个Dispose();如果您不关心何时接到电话(或者即使接到电话),那么您不需要Dispose()
  • 由于您已将它们包装在 using 语句中,我认为您不需要 Dispose

标签: c#


【解决方案1】:

使用using关键字时需要实现IDisposable。来源:MSDN

using 语句允许程序员指定什么时候对象 使用资源应该释放它们。提供给使用对象 语句必须实现 IDisposable 接口。这个界面 提供 Dispose 方法,该方法应该释放对象的 资源。

要回答您的具体问题,我们需要查看更多代码。

如果您的MailMessage 类包含任何非托管资源或流,您肯定必须释放实现IDisposable 并从您的代码中调用Dispose() 方法的资源。

【讨论】:

    【解决方案2】:

    如果您要将它们包装在 using 语句中,则该类需要实现 IDisposable。如果你不这样做,它甚至不会编译。

    如果内存不是托管的,您可能只需要释放内存,但将内部托管引用设置为 null 应该可以满足您的需要。

    回答您的特定问题:

    • 但在这种情况下,我是否需要处理邮件文件?

    我认为你不需要这样做,但这不会有什么坏处,并且会让 GC 清楚地知道对对象的引用少了一个。如果你有类似的东西:

    String name;
    using(MailFile mf = ...) {
        name = mf.Name;
    }
    
    // do something with name
    

    你仍然持有对实际字符串的引用,所以它不会被 GC'd。 mf 应该,但不能保证何时。

    • 我的 Mail 和 Mail 文件不是由 GC 管理和处置吗?

    是的,但只要对对象的引用保存在某处,它们就不会存在。将其设置为 null 且不引用内存中的实际对象意味着 GC 最终会清理它,但不能保证它何时会发生。

    • 也许我应该将 Mail 设为一次性并丢弃其 MailFiles?

    不是必需的,但通常是个好主意。只需让它实现 IDisposable 并在处理时将字段设置为 null。

    • 如果是,最好的方法是什么?

    参见上一点。

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 2021-01-08
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多