正确清洁非一次性物体

时间:2013-10-16 06:17:07

标签: c# .net-4.0 idisposable

关于如何正确使用Dispose Pattern的简短问题。 我在Dispose-method中处理托管资源。

但是,对象 不是一次性的呢? 与StringSystem.Text.Decoder或...

相同

如何正确处理这些对象。如果我不将它们设置为null,如果我不让GC最终确定GC.SupressFinalize(this);,会发生什么?

以下是我如何实现模式的示例:

  private class RequestState : IDisposable {
    const int BufferSize = 1024;
    public StringBuilder RequestData;
    public byte[] BufferRead;
    public WebRequest Request;
    public Stream ResponseStream;
    // Create Decoder for appropriate enconding type.
    public Decoder StreamDecode = Encoding.UTF8.GetDecoder();
    public MyMamespace.Machine Machine;

  public RequestState() {
    BufferRead = new byte[BufferSize];
    RequestData = new StringBuilder(String.Empty);
    Request = null;
    ResponseStream = null;
  }
-------------------------------------------------------------------------------
  #region IDisposable
  private bool disposed = false;

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

  #region IDisposable
  private bool disposed = false;

  public void Dispose() {
    Dispose(true);
    // GC.SupressFinalize(this);         // What happens if I tell the GC that this object is alredy finalized??
  }

  protected virtual void Dispose(bool disposing) {
    if ( !this.disposed ) {
      if ( disposing ) {
        // Dispose managed resources.
        ResponseStream.Dispose();
        Machine = null;                 // Do I need this?
      }
      // release unmanaged ressources

      disposed = true;
    }
  }

  ~RequestState() {
    Dispose(false);
  }
  #endregion
}
#endregion

2 个答案:

答案 0 :(得分:3)

如果他们没有实施一次性模式,那么这些课程的作者会说“这些东西不需要任何特殊的清理”。

你也不需要分配null - GC的全部意义在于它找到了不再使用的东西 - 你不需要试图“帮助它”(而且很多)努力,如果它们有任何影响,实际上阻碍了GC)

你不应该在任何你不是其类 1 的作者的对象上调用GC.SupressFinalize()


1 现在我正在等待评论,指出我目前没有想到的一些优势案例。

答案 1 :(得分:1)

您不需要显式设置对null的引用,但这样做会允许对这些实例进行垃圾回收,即使您的实例在处理后继续被引用也是如此。

我个人认为,当不再需要该引用时,设置对null的引用是一种很好的做法,因为它有助于找到错误。

如果您实施了Disposable模式并且您的对象有终结器,则应始终在GC.SuppressFinalize()方法中的实例上调用Dispose。这样做会通知运行时它不需要调用实例的终结器,因为实例已经被处理掉了。

调用GC.SupressFinalize()不会导致垃圾收集器错过"可以收集的实例。