Is there any downside of calling GC.SuppressFinalize(object) multiple times?
Protected Dispose(bool) method of the dispose pattern checks whether it is called before but there is no such check in the public Dispose() method.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_Disposed)
return;
if (disposing)
{
// Cleanup managed resources.
}
// Cleanup unmanaged resources.
_Disposed = true;
}
~MyClass() { Dispose(false); }
Is it ok to call the Dispose() method of a MyClass instance multiple times?
According to docs: http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx, it sets some bit in object header, so there shouldn't be any implications of calling it multiple times.
Related
The Dispose pattern is notoriously complicated to get right, especially when we have a hierarchy of classes that needs to dispose things at different levels. The recommended implementation is as follow, took from Implement a Dispose method - Microsoft Docs.
using System;
class BaseClass : IDisposable
{
// To detect redundant calls
private bool _disposed = false;
~BaseClass() => Dispose(false);
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
_disposed = true;
}
}
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class DerivedClass : BaseClass
{
// To detect redundant calls
private bool _disposed = false;
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
_disposed = true;
// Call base class implementation.
base.Dispose(disposing);
}
}
What I don't get in this implementation is what advantage we have in adding a _disposed field at each level of the hierarchy? Instead, we could take care of the _disposed only in the top level of the hierarchy (the one implementing directly IDisposable and not care about it in the derived classes.
Something like this:
using System;
class BaseClass : IDisposable
{
// To detect redundant calls
private bool _disposed = false;
~BaseClass()
{
if (_disposed)
{
return;
}
Dispose(false);
_disposed = true;
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
if (_disposed)
{
return;
}
Dispose(true);
GC.SuppressFinalize(this);
_disposed = true;
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
}
}
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class DerivedClass : BaseClass
{
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
// Call base class implementation.
base.Dispose(disposing);
}
}
This is such a widely used code sample that there must certainly be a good reason for it to be implemented with the repeated _disposed at each level, but I just can't find any.
It's a tiny bit more code in the base class, but less to worry about in the derived class, and some repeated information removed.
What else am I missing?
Edit:
As #InBetween correctly says that one drawback of my implementation is that if you'd need to check if your object is disposed in one method of the derived class you won't be able to check it. Let's correct that issue by making it a protected property with a private set.
using System;
class BaseClass : IDisposable
{
// To detect redundant calls
protected bool Disposed { get; private set; } = false;
~BaseClass()
{
if (Disposed)
{
return;
}
Dispose(false);
Disposed = true;
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
if (Disposed)
{
return;
}
Dispose(true);
GC.SuppressFinalize(this);
Disposed = true;
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
}
}
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class DerivedClass : BaseClass
{
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
public void DoSomething()
{
if(Disposed)
{
throw new ObjectDisposedException("Cannot access disposed resource");
}
}
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
// Call base class implementation.
base.Dispose(disposing);
}
}
If you are inheriting from a disposable class, one of two conditions must be true.
Your subcless does not introduce a new disposable resource. In this case you don't need to override Dispose and the question is moot.
Your subclass introduces a new disposable resource. In this case, you're going to override Dispose, insert your own disposal code, then call base.Dispose. The _disposed flag is there to help you remember to prevent your disposal code from executing twice.
You certainly can remove _disposed if you want. But you probably do not care much about the base class' _disposed flag, if it even has one. It worries about what it is disposing, and you worry about yours.
The reason is simple. In your implementation you cant use _disposed in the derived type to check if any method is invoked when the object is already disposed and take the necessary actions. In your implementation you'd need to create your own redundant flag isDisposed which defeats the purpose; you already have one "for free" from the pattern itself following the guidelines.
A case could be made though about making _disposed protected.
What's a good way of writing a test to check that the dispose method of the IDisposable interface is properly releasing unmanaged resources after it is called?
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
// Free any other managed objects here.
}
// Free any unmanaged objects here
theUnmanagedResource.Dispose();
disposed = true;
}
I was thinking I could check if disposed is false after, but it doesn't guarantee that resources are managed.
Another way is setting theUnmanagedResource = null after theUnmanagedResources.Dispose() and check if it is null after in the test cases. But from other posts, they state setting disposed resources to null after is not a good : Setting Objects to Null/Nothing after use in .NET
As described here, you could check if IDispose.Dispose was called directly(object disposed properly), then bool disposing will be true in a virtual void Dispose(bool disposing):
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
~BaseClass()
{
Dispose(false);
}
}
OK, I've read a few things about best practices around IDisposable and I thing I basically get the idea (finally).
My question relates to inheriting from an IDisposable base class. All the examples i see write the same code blocks over and over in the sub-classes and i don't see the advantage.
Why not simply bake a virtual method into the base class, invoke it at the right time from inside the (privately implemented) IDisposable routine so that the sub-classes don't have all that clutter, yet still get a chance do manage their resources?
My proposed base class:
public abstract class DreamDisposableBase : IDisposable
{
private bool _disposed = false;
protected virtual void LocalDispose(bool disposing)
{
}
~DreamDisposableBase()
{
// finalizer being called implies two things:
// 1. our dispose wasn't called (because we suppress it therein)
// 2. we don't need to worry about managed resources; they're also subject to finalization
// so....we need to call dispose with false, meaning dispose but only worry about *unmanaged* resources:
dispose(false);
}
void IDisposable.Dispose()
{
dispose(true); // true argument really just means that we're invoking it explicitly
}
private void dispose(bool disposing)
{
if (!_disposed)
{
// give sub-classes their chance to release their resources synchronously
LocalDispose(disposing);
if (disposing)
{
// true path is our cue to release our private heap variables...
}
// do stuff outside of the conditional path which *always* needs to be done - release unmanaged resources
// tell .net framework we're done, don't bother with our finalizer -
GC.SuppressFinalize(this);
// don't come back through here
_disposed = true;
}
}
}
I wouldn't want every type to have a finalizer. The need to perform any work in a finalizer is very rare. Almost all implementations will not do anything if disposing is true. Finalizers hurt performance because they cause promotion to Gen2, need two collections to be cleaned and calling finalizers is single-threaded.
Most classes do not wrap unmanaged resources, and if they do they should use the SafeHandle types or others. That makes finalizers unnecessary as well.
I do not see any real improvement in your code but as the pattern is non-standard it may be harder for other developers to understand it. To create a derived class using your pattern you need something like this:
class DerivedDreamDisposable : DreamDisposableBase
{
protected override void LocalDispose(bool disposing)
{
if (disposing)
{
// Dispose aggregated objects that are disposable.
}
// Dispose unmanaged resources.
_disposed = true;
base.LocalDispose(disposing);
}
}
Using the standard IDisposable pattern your derived class is something like this:
class DerivedDisposable : DisposableBase
{
bool _disposed;
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose aggregated objects that are disposable.
}
// Dispose unmanaged resources.
_disposed = true;
}
base.Dispose(disposing);
}
}
By deriving from DreamDisposable you avoid to replicate the field to keep track of the disposed state of the object. However, other than that the methods are effectively the same. Also, in your base class LocalDispose is empty and you have moved the code into the private Dispose method but that can be fixed by doing a small refactoring.
However, many classes will not have any unmanaged resources to release and because calling the Dispose method is idempotent (you can call it several times) you often do not have to keep track of the disposed state and your disposable code is simplified to:
protected override void Dispose(bool disposing)
{
if (disposing)
{
_child1.Dispose();
_child2.Dispose();
}
}
If you do not have any unmanaged resources in your inheritance hierarchy you do not need finalizer and the disposing parameter will always be true. Your Dispose method will then be:
protected override void Dispose(bool disposing)
{
_child1.Dispose();
_child2.Dispose();
}
In general avoiding finalizers are good for performance which is why you call GC.SuppressFinalize to undo the harm you did by implement a finalizer.
But in many situations you still need to keep track of the disposed state of an object because you have to throw ObjectDisposedException if methods are invoked after the object has been disposed, and in that case my simplified Disposed methods is too simple. Here is an example on how to handle that without replicating the _disposed flag in each subclass and still use the standard dispose pattern:
class DisposableBase : IDisposable
{
bool _disposed;
~DisposableBase()
{
Dispose(false);
GC.SuppressFinalize(this);
}
public void Dispose()
{
if (_disposed)
return;
Dispose(true);
_disposed = true;
}
public void DoStuff()
{
ThrowIfDisposed();
// Now, do stuff ...
}
protected virtual void Dispose(bool disposing)
{
// Dispose resources ...
}
protected void ThrowIfDisposed()
{
if (_disposed)
throw new ObjectDisposedException(GetType().FullName);
}
}
Any derived class do not need to keep track of the disposed state and instead should use ThrowIfDisposed in all public methods that depends on the object not being disposed.
You say:
My question relates to inheriting from an IDisposable base class. All
the examples i see write the same code blocks over and over in the
sub-classes and i don't see the advantage.
That is not true, in the IDisposable pattern the method:
protected virtual void Dispose(bool disposing)
should be overrided by inheriting classes.
You need to note that the Dispose(bool disposing) method is actually your
LocalDisposing(bool disposing) method. And this fact, I think, is the source of your confusion.
Please read the related section on the seminal book:
Framework Design Guidelines, Second edition
Quoting the book:
If you are inheriting from a class that already implements the
pattern, simply override the Dispose(bool) method to provide aditional
resource cleanup logic
In derived classes the code looks like:
protected override void Dispose(bool disposing)
{
if(disposing)
{
//release own resources
}
}
Also note that in this case you should call GC.SuppressFinalize(this) only in the non-virtual Dispose method.
Also in your code you are implementing the IDisposable interface implicitly, important to be aware of this.
I am writing an excel class and i want to release this unmanaged object automatically.
I'm using IDisposable pattern and write Dispose methods.
Example ;
class MSExcel : IDisposable
{
ApplicationClass excel;
bool disposed;
public MSExcel()
{
disposed = false;
excel = new ApplicationClass();
}
public void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
}
excel.Quit();
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MSExcel()
{
Dispose(false);
}
}
But i have classical error on exc.Quit().
"COM object that has been separated from its underlying RCW".
Have any my mistake in code?
As explained in my answer to your other related question here, you should not be taking actions on reference types from within your finalizer. You enforce this by making use of the bool disposing parameter of your Disposed(bool) method, as you have done. You pass in true, when Disposed(bool) is called explicitly from the void Dispose() method, and pass in false when called from your finalizer, which you have also done.
However, you also need to protect your call to excel.Quit() so that it is not called when Disposed(bool) is called via the finalizer. That is, you should only call excel.Quit() when the bool disposing argument is true.
Therefore, the code for your Disposed(bool) method should look as follows:
public void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
excel.Quit();
}
disposed = true;
}
}
Once done, you could make use of your "MSExcel" class as follows:
using (MSExcel msExcel = new MSExcel)
{
// The code calling your 'MSExcel' object goes here.
}
By doing it this way, when your code gets to the closing bracket, "}", of your using statement block, the Dispose method on your 'MSExcel' class will be called automatically, ensuring that excel.Quit() is called deterministically, and not from a finalizer.
Hope this helps...
Mike
I am getting this warning from FxCop:
"'RestartForm' contains field 'RestartForm.done' that is of IDisposable type: 'ManualResetEvent'. Change the Dispose method on 'RestartForm' to call Dispose or Close on this field."
Ok, I understand what this means and why this is what needs to be done... Except System.Windows.Forms.Form doesn't allow you to override either .Close() or .Dispose(), so what to do? Currently I'm running with this solution:
private void RestartForm_FormClosing(object sender, FormClosingEventArgs e)
{
done.Set();
done.Close();
}
Which works as intended for my application... But FxCop still shows this message. Am I covered and can I safely ignore it, or is there another way I should be doing this?
You need to override the Dispose method from Form
Typically this is automatically overridden in the RestartForm.Designer.cs file, so you will need to move the dispose into your code file so that you can add whatever code you need to add without it being rewritten by the designer.
In the RestartForm.cs
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
// Dispose stuff here
}
base.Dispose(disposing);
}
I use this method :)
Image bgImage = Image.FromFile(workingDir + "\\" + button.BackgroundImage);
currentButton.Image = bgImage;
currentButton.Disposed += (Object sndr, EventArgs evnt) => bgImage.Dispose();
If RestartForm extends System.Windows.Forms.Form, you should be able to override Dispose(bool disposing). You should properly implement this for your "RestartForm" class to dispose of your IDisposables.
It should look like:
public override Dispose(bool disposing)
{
if (disposing)
{
// Dispose was called from user code. Dispose of managed resources here.
done.Dispose();
}
// Dispose of unmanaged resources here, and invoke base dispose.
base.Dispose(disposing);
}
You need to override the Dispose method, this method comes from the Control base class
protected override void Dispose(bool disposing)
{
if (disposing)
{
event.Dispose();
}
base.Dispose(disposing);
}