Reputation: 82367
I am confused about dispose. I am trying to get my code disposing resources correctly. So I have been setting up my classes as IDisposable
(with a Dispose
method) them making sure that the Dispose
method gets called.
But now FXCop is telling me lots of stuff about disposing = false
and calling Dispose(false)
.
I don't see a Dispose
method that takes a bool. Do I need to make one? If so, why? Why not just have a method that gets called when it is disposing?
I saw some code here: CA1063: Implement IDisposable correctly - Microsoft Docs that shows how to make a Dispose
method that takes a bool
. It says it is for native vs managed resourses. But I thought the whole point of dispose was for unmanaged resourses only.
Also, the line that FXCop is complaining about is this:
~OwnerDrawnPanel()
{
_font.Dispose();
}
It says:
CA1063 : Microsoft.Design : Modify 'OwnerDrawnPanel.~OwnerDrawnPanel()' so that it calls Dispose(false) and then returns.
But Font
does not have a Dispose(bool)
on it (that I can find).
Why do I need a Dispose(bool)
? and if I do, why doesn't Font have it? and since it does not have it, why is FXCop asking me to use it?
Thanks for all the great answers. I think I understand now. Here is
Disposing of "unmanaged" resources falls into two categories:
Bitmap
, Font
etc), but still need Dispose
to be called to clean them up properly.Dispose(bool)
is used to tell the difference between the two:
Dispose
is directly called on your object, you want to free both kinds of "unmanaged" resources.Upvotes: 45
Views: 25259
Reputation:
Dispose(bool)
is not meant to be public and that is why you don't see it on Font
.
In case some user of your class forgets to call Dispose
on your method, you will release the unmanaged resources only by making a call to Dispose(false)
in the Finalizer
.
In case IDispose
is called correctly, you call the Dispose
on managed resources and also take care of the unmanaged.
The flag is to distinguish the two cases.
It is a pattern recommended by MSDN.
Upvotes: 8
Reputation: 25694
IDisposable
provides a method with the signature
public void Dispose()
Microsoft best practices (Implement a Dispose method) recommend making a second private method with the signature
private void Dispose(bool)
Your public Dispose
method and finalizer should call this private Dispose
method to prevent disposing managed resources multiple times.
You can fix the warning you are getting by either implementing IDisposable
and disposing of your font object in the dispose method, or creating a Dispose(bool)
method in your class, and make your finalizer call that method.
Upvotes: 10
Reputation: 21
I think Dispose(true)
will free both the managed and unmanaged resource as we need to not call finalize again that's why we write GC.SupressFinalize()
after Dispose(true)
.
We call Dispose(false)
in destructors to free unmanaged resources and will be called by Runtime and not user's code.
Upvotes: 2
Reputation: 1694
The pattern of implementing a public public void Dispose()
, protected virtual void Dispose(bool)
, and ~ClassName()
finalizers is a best practice recommended by Microsoft as a way to neatly organize your cleanup code for both managed and unmanaged resources.
Basically, the code that uses your Disposable
class should call Dispose()
, but if it doesn't, the finalizer ~ClassName()
will get called by Garbage Collection, and based on which one of those is used, you set the argument to Dispose(bool)
as true or false, and in your Dispose(bool)
, you only clean up managed resources if the argument is true.
The warning you are getting seems to specifically recommend that you use this practice in your finalize method ~ClassName()
.
Upvotes: 0
Reputation: 10940
FxCop says you should implement the Disposable pattern like described here. Note that you should not use finalizers for disposing managed resources like _font
is. Finalizers are used for cleaning up unmanaged resources. If you do not execute the cleanup logic in the Dispose method of your (sub)class they are executed non-deterministically by the garbage collector.
Upvotes: 3
Reputation: 10600
You should almost never need to use finalizers. They are only for classes that directly contain unmanaged resources, and in .NET 2.0+ those should be wrapped in SafeHandle.
Upvotes: 2
Reputation: 80754
Also please note that it is very rarely that you need to do anything in the destructor. Regularly, everything is taken care of by the garbage collector. For example, in your code, you don't need to dispose the _font
object in the OwnerDrawnPanel
's destructor. Since the panel is getting cleaned up by the GC, so will be _font
, because panel was the only one who referenced it, right?
Generally, if you own disposable objects, you only need to dispose them when your own Dispose
method was called. But NOT in the destructor. When your destructor is running, you can bet that all your aggregated objects are being cleaned up as well.
Upvotes: 2
Reputation: 803
I found a good article about correct implementation of IDispose interface: http://msdn.microsoft.com/en-us/library/ms244737(v=vs.80).aspx
Upvotes: 0
Reputation: 103365
Agreeing with Kumar, the Dispose(bool disposing)
pattern is also documented on MSDN. The distinction is not between managed and unmanaged resources, but whether Dispose
is being called by your code or the runtime.
Upvotes: 1
Reputation: 1015
Dispose(bool)
is a pattern to implement Finalize
and Dispose
to Clean Up Unmanaged Resources , see this for detail
Upvotes: 11