About Dispose

S

Sam Sungshik Kong

Hello!

A disposable object's Dispose() method can be called either explicitly by
the programmer or implicitly during finalization.
If you call Dispose, the unmanaged resources are released earlier.
Thus, if you think the unmanaged resources are important, you call Dispose
explicitly.

My question is what's the criteria to decide the unmanaged resources are
important.

I think...
files are important.
DB connections are important.

What about window handles?
What about Graphics?

I want to hear what you think about it.

Thanks.

Sam
 
N

Nicholas Paldino [.NET/C# MVP]

Sam,

If the object in question implements IDisposable, then you should call
it as soon as you possibly can. The reason for this is that it represents
some resource that should be released right away (wether it is memory, file
handles, database connections, etc, etc).

If you let them linger around, then its true, a proper implementation of
the IDisposable method will make sure that they *eventually* get cleaned up,
but in order to keep your app (and the rest of the system running)
efficiently, it is in your best interests to call the Dispose method as soon
as you are done with them.

Hope this helps.
 
M

Mickey Williams [C# MVP]

A disposable object's Dispose() method can be called either explicitly by
the programmer or implicitly during finalization.

This is not correct. The finalizer is called -- not the Dispose method.

What about window handles?
What about Graphics?

If you have a managed reference to an object that owns an unmanaged handle,
it probably implements IDisposable. If you have strong (and sole) ownership
over that instance, you should implement IDisposable so that you can project
the Dispose pattern properly. There is no point in this case in implementing
a finalizer, as finalization occurs too late for you to try to clean up
these instances.

OTOH, if you have a raw unmanaged handle that you've aquired via P/Invoke or
other means, you should clean up that handle in code paths for Dispose and
your finalizer. In your Dispose method, you should suppress finalization.
 
S

Sam Sungshik Kong

Hi!

Mickey Williams said:
This is not correct. The finalizer is called -- not the Dispose method.

I found this statement in MSDN.

Because the Dispose method must be called explicitly, objects that implement
IDisposable must also implement a finalizer to handle freeing resources when
Dispose is not called.

And I think that finalizer is a safety device for a case when you don't
explicit call Dispose.
When I said that Dispose() is implicitly called, I meant that the finalizer
calls Dispose().

Am I missing something?
If you have a managed reference to an object that owns an unmanaged handle,
it probably implements IDisposable. If you have strong (and sole) ownership
over that instance, you should implement IDisposable so that you can project
the Dispose pattern properly. There is no point in this case in implementing
a finalizer, as finalization occurs too late for you to try to clean up
these instances.

OTOH, if you have a raw unmanaged handle that you've aquired via P/Invoke or
other means, you should clean up that handle in code paths for Dispose and
your finalizer. In your Dispose method, you should suppress finalization.


--
Mickey Williams
Author, "Visual C# .NET Core Ref", MS Press
www.neudesic.com
www.servergeek.com


Thanks.

Sam
 
S

Sam Sungshik Kong

Hi!
Thanks for the answer.
I have some further questions.

Nicholas Paldino said:
Sam,

If the object in question implements IDisposable, then you should call
it as soon as you possibly can. The reason for this is that it represents
some resource that should be released right away (wether it is memory, file
handles, database connections, etc, etc).

But most of classes in .net framework implements IDisposable.
(including all components)

Let's say you create a button dynamically, and remove it would you Dispose
it?

//This is a useless example.
public void F()
{
Button b = new Button();
...
b.Dispose(); //would you call this?
}

Another question is...
Do I have to call Dispose() when I use a using statement?

using(MyClass o = new MyClass()) //MyClass implements IDisposable.
{
...
o.Dispose(); //is this needed?
}



If you let them linger around, then its true, a proper implementation of
the IDisposable method will make sure that they *eventually* get cleaned up,
but in order to keep your app (and the rest of the system running)
efficiently, it is in your best interests to call the Dispose method as soon
as you are done with them.

Hope this helps.

Sam
 
N

Nicholas Paldino [.NET/C# MVP]

Sam,

See inline:
But most of classes in .net framework implements IDisposable.
(including all components)

Let's say you create a button dynamically, and remove it would you Dispose
it?

//This is a useless example.
public void F()
{
Button b = new Button();
...
b.Dispose(); //would you call this?
}

In that case, yes, I would, but in the general case, no, I would not.
When it comes to controls in the System.Windows.Forms namespace, I would not
call Dispose, only because if a control is a child of another control, then
when the form dissapears, it is going to destroy all child windows as well.

However, if I removed a control from a form, then I would call Dispose,
for good measure.
Another question is...
Do I have to call Dispose() when I use a using statement?

using(MyClass o = new MyClass()) //MyClass implements IDisposable.
{
...
o.Dispose(); //is this needed?
}

No, you do not. That's the beauty of the using statement. The type
must implement IDisposable, and when the block is exited, it will call
Dispose on the member variable declared in for that scope.
 
S

Sam Sungshik Kong

OK!
Now everything's clear and consistent.
Thank you very much.

Sam

Nicholas Paldino said:
Sam,

See inline:
But most of classes in .net framework implements IDisposable.
(including all components)

Let's say you create a button dynamically, and remove it would you Dispose
it?

//This is a useless example.
public void F()
{
Button b = new Button();
...
b.Dispose(); //would you call this?
}

In that case, yes, I would, but in the general case, no, I would not.
When it comes to controls in the System.Windows.Forms namespace, I would not
call Dispose, only because if a control is a child of another control, then
when the form dissapears, it is going to destroy all child windows as well.

However, if I removed a control from a form, then I would call Dispose,
for good measure.
Another question is...
Do I have to call Dispose() when I use a using statement?

using(MyClass o = new MyClass()) //MyClass implements IDisposable.
{
...
o.Dispose(); //is this needed?
}

No, you do not. That's the beauty of the using statement. The type
must implement IDisposable, and when the block is exited, it will call
Dispose on the member variable declared in for that scope.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
implementation
of cleaned
up, explicitly
by

Sam
 
M

Mickey Williams [C# MVP]

If you have a finalizer, you should always implement IDisposable, but the
reverse is not true. That statement in MSDN is wrong, and I've reported it
as broken. In nearly all cases a finalizer should not just call Dispose --
you should only implement a finalizer if you are dealing directly with
unmanaged respources, either explicitly with handles, or (less frequently)
implicitly with state through P/Invoke.

Lets say you have a class X:

class X
{
SqlConnection c;
...
}

This is a good cadidate for implementing IDisposable -- the class X can
simply forward Dispose() calls to the embedded instance of SqlConnection
(subject to basic rules). It is not a candidate for implementing a
finalizer. During finalization, there is no point to attempting the same
behavior, as the SqlConnection instance is also queued for finalization, and
in fact may have already been finalized. Disposal is now irrelevant, and
may, in fact lead to race conditions between the finalizer and disposal
threads. By implementing a finalizer, X has simply added to the finalizer
queue's workload, to zero real effect.

--
Mickey Williams
Author, "Visual C# .NET Core Ref", MS Press
www.neudesic.com
www.servergeek.com
 
S

Sam Sungshik Kong

Mickey Williams said:
If you have a finalizer, you should always implement IDisposable, but the
reverse is not true. That statement in MSDN is wrong, and I've reported it
as broken. In nearly all cases a finalizer should not just call Dispose --
you should only implement a finalizer if you are dealing directly with
unmanaged respources, either explicitly with handles, or (less frequently)
implicitly with state through P/Invoke.

The statement is wrong?
I'm surprised.
Can you post when you get a repsonse from MS?

Let's assume what you say is right...
What happens if I forget to call Dispose() of an object that is IDisposable
and GC calls the finalizer which doesn't call Dispose()?
Then there's no way to release the unmanaged resource?

Am I wrong?
Lets say you have a class X:

class X
{
SqlConnection c;
...
}

This is a good cadidate for implementing IDisposable -- the class X can

I disagree.
class X is not implementing IDisposable.
class X has a field of IDisposable.

To implement IDisposable, it should be like

class X: IDisposable
{
...
}

Thanks.
Sam
 
G

Guest

My question is what's the criteria to decide the unmanaged resources are
important.

I think...
files are important.
DB connections are important.

DB Note: If you read the documentation for the IDisposable interface you
will note that SqlTransaction & SqlDataReader both implement IDisposable but
SqlConnection does NOT - this is due to connection pooling I think. The
Oracle DB classes are similiar in behavior...

2 more good IDisposable cases:

COM objects: often times you want to have explicit control over the lifetime
of a COM reference. Implementing IDispose on a class that holds COM
references is an excellent way to control COM reference lifetime. See also
Marshal.Release()...

Thread affinity: any object or resource that must be manipulated by the
thread that instantiated it can benefit from IDispose. In such cases you can
manually Dispose from the instantiating thread. If you don't manually
Dispose then you are 100% guaranteed that the finalizer will be called by a
different framework worker thread...

Also, it can be a pain to implement, but here's an article on proper
implementation of the "IDisposable" pattern:

http://msdn.microsoft.com/library/d.../en-us/cpgenref/html/cpconFinalizeDispose.asp
What about window handles?
What about Graphics?

Yes - because many GUI objects have high thread affinity...

--Richard
 
G

Guest

MY BAD-

After I posted I rememembered that I have code that uses SqlConnection in a
using statement, and that is ONLY possible if SqlConnection implements
IDispose...
DB Note: If you read the documentation for the IDisposable interface you
will note that SqlTransaction & SqlDataReader both implement IDisposable but
SqlConnection does NOT - this is due to connection pooling I think. The
Oracle DB classes are similiar in behavior...

You can use SqlConnection in a using statement - I assume that base class
implements IDispose...

--Richard
 
M

Mickey Williams [C# MVP]

Yes the statement is wrong. There is a large amount of information
available, as well as logic and common sense, which proves it to be wrong.
The statement is wrong?
I'm surprised.

Don't be -- there's a lot of documentation.
Can you post when you get a repsonse from MS?

They probably won't reply. They get a lot of feedback email. See previous
inline comment.
Let's assume what you say is right...
Lets.

What happens if I forget to call Dispose() of an object that is
IDisposable
and GC calls the finalizer which doesn't call Dispose()?
Then there's no way to release the unmanaged resource?

If you directly control the unmanaged resources (as opposed to holding a
reference to an instance of a managed type such as SqlConnection), then you
should implement a finalizer, and that finalizer should deal with the
unmanaged resource. In the overwhelming majority of cases, when you work
with a resource such as a database connection, you do it through a class
like SqlConnection and there's no need for your class to request
finalization. You should implement IDisposable if you have strong, sole
ownership over the disposable object so that you can forward disposal
requests.

See my previous post. There is no advantage to implementing a finalizer if
you do not directly control unmanage resources, or have special release
requirements due to p/Invoke. What are you hoping to accomplish? The runtime
is already disposing of the object you refer to. In fact, it might get rid
of it faster if your class hadn't registered for finalization and gotten in
the way.
I disagree.
class X is not implementing IDisposable.
class X has a field of IDisposable.

I don't know if you're being deliberatly obtuse, but I said it was a
*candidate for implementing IDisposable*.
To implement IDisposable, it should be like

I'm a C# MVP, you can assume I know the C# syntax.
 
M

Mickey Williams [C# MVP]

You can use SqlConnection in a using statement - I assume that base class
implements IDispose...

SqlConnection implements IDisposable via the Component base class and
IDbConnection, sort of like this:

class Component: IDisposable
{
public void Dispose(){
Dispose(true);
}
protected virtual void Dispose(bool disposing){}
}

interface IDbConnection: IDisposable
{
}

class SqlConnection: Component, IDbConnection
{
protected override void Dispose(bool disposing) {
base.Dispose (disposing);
}
}
 
R

Richard Blewett [DevelopMentor]

Well in that case the documentation is fundementally wrong. SImply looking at SqlConnection in Reflector shows you that SqlConnection does implement IDisposable - it, however, implements it explcitly because having both a Close and a Dispose method on the public face of the type would be confusing. As far as connection pooling and Dispose are concerned, there is a whole bunch of misinformation out there about this. Dispose simply calls Close and clears the connection string (so you can't call Open again). It does not, as some people claim, remove the connection from the connection pool.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


DB Note: If you read the documentation for the IDisposable interface you
will note that SqlTransaction & SqlDataReader both implement IDisposable but
SqlConnection does NOT - this is due to connection pooling I think. The
Oracle DB classes are similiar in behavior...




---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.775 / Virus Database: 522 - Release Date: 08/10/2004



[microsoft.public.dotnet.languages.csharp]
 
S

Scott Allen

But Close and Dispose are on the public face (IDisposable is
implemented implicitly). I think this is the primary reasons for all
the confusion that does surround SqlConnection, and all the code you
see that calls Close and Dispose (and sets the reference to null and
so on).
 
R

Richard Blewett [DevelopMentor]

lol, I could have sworn IDisposable was implemented explicitly by SqlConnection - I wonder what class I was thinking of - my bad

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

But Close and Dispose are on the public face (IDisposable is
implemented implicitly). I think this is the primary reasons for all
the confusion that does surround SqlConnection, and all the code you
see that calls Close and Dispose (and sets the reference to null and
so on).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top