Warning 75 CA1816 : Microsoft.Usage : Change 'xxx.Dispose()' to call
'GC.SuppressFinalize(object)'. This will prevent unnecessary
finalization of the object once it has been disposed and it has fallen
out of scope.
None of my classes have a finalizer, they all simply have the
following (or very simular to the following)
----------
private bool disposed = false;
public void Dispose() { Dispose(true); }
protected virtual void Dispose(bool disposing) {
if(!disposed) {
if(disposing && slimLock != null) slimLock.Dispose();
disposed = true;
}
}
----------
Joe Duffy's Weblog (http://www.bluebytesoftware.com/blog/2005/04/08/
DGUpdateDisposeFinalizationAndResourceManagement.aspx)
--Says not to call Dispose if my class doesn't have the "~MyClass()"
finalizer method.
MSDN (http://msdn2.microsoft.com/en-us/library/ms182269.aspx)
--Says, basically, don't ignore this warning and to add the code.
Should I be calling the SupressFinalize anyway (IE doesn't hurt
anything performance wise), or just ignore the Code Analysis warning?
Or 'something strange with my code because I dont get the warning'
kind of thing?
Thanks :) NB
//the dispose pattern
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//release objects
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
--
Misbah Arefin
https://mcp.support.microsoft.com/profile/MISBAH.AREFIN
http://www.linkedin.com/in/misbaharefin
> [...]
> Should I be calling the SupressFinalize anyway (IE doesn't hurt
> anything performance wise), or just ignore the Code Analysis warning?
> Or 'something strange with my code because I dont get the warning'
> kind of thing?
The thing that's strange about your code is that you haven't implemented a
finalizer for a class that implements IDisposable.
So, add the finalizer as well as the call to SuppressFinalize() when
"disposing" is true (you should be calling "Dispose(false);" from the
finalizer).
Pete
I just found it very strange that they'd have us call a
SuppressFinalize when the class has no filalizer (IE, no "~MyClass()
{}"). The class has no unmanaged clean-up, so I'm 99% sure my class
doesn't want to create an empty "~MyClass() {}", else it might get the
performance hit when its not needed.
Also when choosing the .NET2.0 version of CA1816 it says "Cause: A
type implements System.IDisposable.Dispose, has a finalizer, and
Dispose does not call System.GC.SuppressFinalize(System.Object)."
http://msdn2.microsoft.com/en-us/library/ms182269(VS.80).aspx
But when choosing the .NET3.5 version of CA1816, all reference about
the "has a finalizer" are removed under cause.
http://msdn2.microsoft.com/en-us/library/ms182269.aspx
Does it mean that in .NET3.5 they added some kind of code optimization
that realizes I didn't overload the finalizer object and thus the
"SupressFinalizer" line basically does nothing, so just add it anyway
to be safe for the future is what code analysis is telling me?
--Joe Duffy's Weblog Also States--
Simple Example w/out Finalize (C#): For the majority of types
implementing the Dispose pattern, you will not need to implement your
own Finalize method. This example shows the simple case, for example
when using a SafeHandle to take care of the implicit cleanup:
And then shows an example where it does not call SupressFinalize, but
this is a couple years old so might be .NET 2.0 specific (not related
to .NET 3.5).
I realize having the Supress there probably doesn't affect much (even
in .NET 2.0) if you don't have a finalizer, but I'm always curious
about little things like this.
NB
> [...]
> Also when choosing the .NET2.0 version of CA1816 it says "Cause: A
> type implements System.IDisposable.Dispose, has a finalizer, and
> Dispose does not call System.GC.SuppressFinalize(System.Object)."
> http://msdn2.microsoft.com/en-us/library/ms182269(VS.80).aspx
>
> But when choosing the .NET3.5 version of CA1816, all reference about
> the "has a finalizer" are removed under cause.
> http://msdn2.microsoft.com/en-us/library/ms182269.aspx
Look more carefully at the explanation of the latter. In particular, this
part:
To prevent derived types with finalizers from having to
re-implement [System][.][IDisposable] and to call it,
unsealed types without finalizers should still call
GC.SuppressFinalize.
In other words, they are saying that if your class isn't sealed, then even
if you don't implement your own finalizer, you should still call
SuppressFinalize() in your Dispose() method. That way, derived types only
have to implement the protected Dispose(bool) method, and can rely on your
base class implementation to deal with finalizer issues.
> Does it mean that in .NET3.5 they added some kind of code optimization
> that realizes I didn't overload the finalizer object and thus the
> "SupressFinalizer" line basically does nothing, so just add it anyway
> to be safe for the future is what code analysis is telling me?
The call to SuppressFinalize() is very inexpensive in any case. If you
don't have a finalizer, then I'd agree that strictly speaking it's not
necessary. However, it does seem to me that it's good form to go ahead
and use it. And that's what the warning is telling you.
Pete
Ahh, thats exactly what I was looking for thanks :) I remember
reading the .NET 2.0 version, and then skimming the .NET 3.5 version
after realizing I was on .NET 2.0. I should of been more attentitive
to the newer one :)
I understand now why it should have SuppressFinalize :) Thanks
Kindly.
NB