Public class MyClass:IDisposable
{
private bool IsDisposed=false;
public void Dispose()
{
Dispose(true);
GC.SupressFinalize(this);
}
protected void Dispose(bool Diposing)
{
if(!IsDisposed)
{
if(Disposing)
{
//Clean Up managed resources
/////////////////////////////////////////////
aMember.Dispose();
bMember.Dispose();
cMember.Dispose();
////////////////////////////////////////////
}
//Clean up unmanaged resources
////////////////////////////////////////////////
some pinvoke resource releases
for example 'paired' api calls
like this from this page
http://safari.oreilly.com/0321174038/app04
//////////////////////////////////////////////
}
IsDisposed=true;
}
~MyClass()
{
Dispose(false);
}
Is that right?
-----------------
Yes, that is it.
The difference lies not in whether there is an unmanaged resource. Of
course there is an unmanaged resource. SqlConnection, File, Socket, all of
these have unmanaged resources. The point is to get them cleaned up at the
right time without messing up the garbage collector.
If somebody called Dispose on your object, then it is still reachable.
Therefore you should ask all the resources to dispose as well.
If the finalizer is called on your object, then it is not reachable. If you
have private resources, then they are also not reachable. If they are .NET
classes, then they have their own finalizers which will be run automatically
at about the same time as yours, you do not need to call them. In fact it
would be an error to do so because:
(1) their finalizers might already have run
(2) if you access the object, you will prevent it from being freed during
this garbage collection cycle (resurrection)
(3) if you are subscribed to any events of the object, and resurrect it,
then it will resurrect your object as well
The key thing is, your client only tells you to dispose, so you have to pass
the message along. The garbage collector will tell each managed class to
finalize, so you don't tell other .NET classes when you are being finalized.
But the garbage collector doesn't know about anything except managed
classes, so if you called p/invoke, you need to clean that up yourself.
Ok?