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);
}
Related
MS advices that base class should provide protected virtual void Dispose(bool disposing) in the derived classes. I have an existing class written much earlier which does not provide such function. By knowing the fact base class is Disposable, can we simply use the following in any derived class?
class Base : IDisposable
{
//This somehow disposes it's resources
}
class Derived : Base
{
bool disposed;
private void PrivateDispose(bool disposing)
{
if (disposed) return;
if (disposing) {
// Cleanup managed resources
// ...
// Simply dispose base class
base.Dispose();
}
// Cleanup unmanged resources if any
// ...
disposed = true;
}
public void Dispose()
{
PrivateDispose(true);
GC.SuppressFinalize(this);
}
// Only provide Finalizer if we have unmanaged resources
~Derived()
{
PrivateDispose(false);
}
}
Yes, you can. The reason MS recommends this is to make it easy for any implementers of derived types to override the existing Dispose(bool disposing) method, since the public void Dispose() implemented by the IDisposable interface isn't virtual.
Note that you should use this pattern. Change:
private void PrivateDispose(bool disposing)
To:
protected virtual void Dispose(bool disposing)
So if anyone potentially needs to extend your class, he can simply override your method.
In general, here are some more guidelines for implementing IDisposable:
Dispose should meet the following conditions:
1) Be safely callable multiple times
2) Release any resources
associated with the instance
3) Call the base class's Dispose method,
if necessary
4) Suppress finalization of this class to help the GC by
reducing the
number of objects on the finalization queue.
5) Dispose shouldn't generally throw exceptions, except for very serious
errors that are particularly unexpected (ie, OutOfMemoryException).
Ideally, nothing should go wrong with your object by calling Dispose.
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.
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.
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