Reputation: 183
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
Upvotes: 1
Views: 2918
Reputation: 1875
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.
Upvotes: 2
Reputation: 239824
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.
Upvotes: 4