Question

Short question on how to use the Dispose Pattern completely correctly. I am disposing managed resources in my Dispose-method.

But, what about objects which are not disposable? Like String or System.Text.Decoder or...

How do i handle these objects correctly. What happens if i don't set them to null an if i don't let the GC finalize them GC.SupressFinalize(this);?

Here is an example of how do I implemented the Pattern:

  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
Était-ce utile?

La solution

If they don't implement the disposable pattern then the authors of those classes are saying "these things don't need any special cleaning up".

And you don't need to assign null either - the whole point of the GC is that it finds the stuff that's no longer used - you don't need to try to "help it" (and many efforts, if they have any effect at all, actually hinder the GC)

You shouldn't ever call GC.SupressFinalize() on any object where you're not the author of its class1.


1And now I'm waiting for a comment that points out some edge case that I don't currently have in mind.

Autres conseils

You do not need to explicitly set references to null, but doing so will allow those instances to be garbage collected even if your instance continues to be referenced after it is disposed.

My personal opinion is that setting references to null when that reference is no longer need is a good practice as it helps locate bugs.

If you implement the Disposable pattern and your object has a finalizer, you should always call GC.SuppressFinalize() on the instance within your Dispose method. Doing so informs the runtime that it does not need to call the instance's finalizer, as the instance has already been disposed.

Calling GC.SupressFinalize() will not cause the garbage collector to "miss" instances that may be collected.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top