469,356 Members | 2,013 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,356 developers. It's quick & easy.

object.close() or object = null?

so im trying to be good and not leave anything hanging open but i guess ive
seen a variety of ways to kill objects.. is there like a recommended way?

basically im looking for best practices for handling object destruction.

Thanks
Justin
Sep 10 '07 #1
20 12959
Justin,

If the type of the object instance implements IDisposable, then you
should call the Dispose method on that interface implementation. The
"using" construct is handy for that:

using (MyObject myObject = new MyObject())
{
// Use myObject here.
}

When the scope is exited (because of return value, exception, or the
code just exits the scope) the Dispose method is going to be called on
MyObject's implementation of IDisposable.

If a type doesn't implement IDisposable, then you don't have to do
anything with the object, the CLR will take care of it eventually through
GC.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Justin Rich" <jr******@yahoo.spam.comwrote in message
news:u7**************@TK2MSFTNGP04.phx.gbl...
so im trying to be good and not leave anything hanging open but i guess
ive seen a variety of ways to kill objects.. is there like a recommended
way?

basically im looking for best practices for handling object destruction.

Thanks
Justin

Sep 10 '07 #2
Justin Rich wrote:
so im trying to be good and not leave anything hanging open but i guess ive
seen a variety of ways to kill objects.. is there like a recommended way?

basically im looking for best practices for handling object destruction.
Like most things, there is no one size fits all answer. If the object
is an object that connects to a resource, such as a SQL database, then
it likely has a close method that should be called. If the object in
its hierarchy implements IDisposable then you want to make sure its
Dispose method is called either explicitly or implicitly by creating the
object with the "using" keyword. If the object is just an RTW for an
unmanaged COM object then you'll want to properly release the underlying
come object, possibly with a call to Marshal.ReleaseComObject. It is
rare that I've seen setting the object to null to have a benefit.

But the answer varies depending on what the object is, the scope of the
object, the needed lifetime of the object, etc.
--
Tom Porterfield
Sep 10 '07 #3

"Tom Porterfield" <tp******@mvps.orgwrote in message
news:OH****************@TK2MSFTNGP02.phx.gbl...
Justin Rich wrote:
>so im trying to be good and not leave anything hanging open but i guess
ive seen a variety of ways to kill objects.. is there like a recommended
way?

basically im looking for best practices for handling object destruction.

Like most things, there is no one size fits all answer. If the object is
an object that connects to a resource, such as a SQL database, then it
likely has a close method that should be called. If the object in its
hierarchy implements IDisposable then you want to make sure its Dispose
method is called either explicitly or implicitly by creating the object
with the "using" keyword. If the object is just an RTW for an unmanaged
COM object then you'll want to properly release the underlying come
object, possibly with a call to Marshal.ReleaseComObject. It is rare that
I've seen setting the object to null to have a benefit.
Whether the actual cleanup action is Close, Flush, ReleaseComObject, or
whatever, nearly every object provides a Dispose method that "does the right
thing". If it implements IDisposable, call Dispose. Any other cleanup
requirement should be considered a bug.

The only use of "variable = null;" is when you're in the main loop of the
thread, where your function won't close for a very long time. Or if the
variable is a class member. Especially static members of classes will
always be reachable so the GC sees them as being in-use and never cleans
them up, so in that case you should null it out.
>
But the answer varies depending on what the object is, the scope of the
object, the needed lifetime of the object, etc.
--
Tom Porterfield

Sep 10 '07 #4
Justin Rich <jr******@yahoo.spam.comwrote:
so im trying to be good and not leave anything hanging open but i guess ive
seen a variety of ways to kill objects.. is there like a recommended way?

basically im looking for best practices for handling object destruction.
You can't "kill" an object at all.

You can ask it to release any non-memory resource it has, usually by
calling Dispose() which can be performed automatically with a "using"
statement.

You can't force an object to be destroyed, however. Setting a variable
to null doesn't force this, for three reasons:

1) There might be other references to the object
2) The object will only be destroyed when the garbage collector kicks
in (and only then if it's collecting that generation)
3) If the object has a finalizer, it will last until the subsequent
collection

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Sep 10 '07 #5
Ben Voigt [C++ MVP] wrote:
Whether the actual cleanup action is Close, Flush, ReleaseComObject, or
whatever, nearly every object provides a Dispose method that "does the right
thing". If it implements IDisposable, call Dispose. Any other cleanup
requirement should be considered a bug.
And IMHO the point here is that Close, etc. is not a replacement for
Dispose. It's usually there to allow a specific kind of behavior that
is not necessarily equivalent to calling Dispose.

It's not an either/or thing. If a class implements IDisposeable, you
need to call Dispose when you're done with the object. You may also
want to use a similar (but not identical) method also implemented by the
class.

Pete
Sep 10 '07 #6
Ben Voigt [C++ MVP] wrote:
"Tom Porterfield" <tp******@mvps.orgwrote in message
>Like most things, there is no one size fits all answer. If the object is
an object that connects to a resource, such as a SQL database, then it
likely has a close method that should be called. If the object in its
hierarchy implements IDisposable then you want to make sure its Dispose
method is called either explicitly or implicitly by creating the object
with the "using" keyword. If the object is just an RTW for an unmanaged
COM object then you'll want to properly release the underlying come
object, possibly with a call to Marshal.ReleaseComObject. It is rare that
I've seen setting the object to null to have a benefit.

Whether the actual cleanup action is Close, Flush, ReleaseComObject, or
whatever, nearly every object provides a Dispose method that "does the right
thing". If it implements IDisposable, call Dispose. Any other cleanup
requirement should be considered a bug.
A runtime callable wrapper is created whenever you interop to a COM
interface pointer from managed code. You should use
Marshal.ReleaseComObject to free the underlying COM object. Yes, you
can wait for the runtime to do this for you, just as you can wait for it
to dispose of an object that implements IDisposable, but that can lead
to memory issues. Having to call ReleaseComObject on a RCW is no more a
bug than needing to call Dispose on an IDisposable object.
--
Tom Porterfield
Sep 10 '07 #7
Thanks for the responses everyone. That helps out a lot.

Justin

"Justin Rich" <jr******@yahoo.spam.comwrote in message
news:u7**************@TK2MSFTNGP04.phx.gbl...
so im trying to be good and not leave anything hanging open but i guess
ive seen a variety of ways to kill objects.. is there like a recommended
way?

basically im looking for best practices for handling object destruction.

Thanks
Justin

Sep 10 '07 #8
Is that to say that if the object implements IDisposable AND has its own
close method that i should, to be safe, call both of them?

object.close();
object.dispose();

i doubt doing this would hurt anything and for the most part should be more
helpful than wasteful?

thanks
Justin
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:13*************@corp.supernews.com...
Ben Voigt [C++ MVP] wrote:
>Whether the actual cleanup action is Close, Flush, ReleaseComObject, or
whatever, nearly every object provides a Dispose method that "does the
right thing". If it implements IDisposable, call Dispose. Any other
cleanup requirement should be considered a bug.

And IMHO the point here is that Close, etc. is not a replacement for
Dispose. It's usually there to allow a specific kind of behavior that is
not necessarily equivalent to calling Dispose.

It's not an either/or thing. If a class implements IDisposeable, you need
to call Dispose when you're done with the object. You may also want to
use a similar (but not identical) method also implemented by the class.

Pete

Sep 10 '07 #9
Justin Rich wrote:
Is that to say that if the object implements IDisposable AND has its own
close method that i should, to be safe, call both of them?
What Nicholas said. :)
Sep 10 '07 #10
If an object implements IDispose then call the Dispose method. If not then
set it's reference to null.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
"Justin Rich" <jr******@yahoo.spam.comwrote in message
news:u7**************@TK2MSFTNGP04.phx.gbl...
so im trying to be good and not leave anything hanging open but i guess
ive seen a variety of ways to kill objects.. is there like a recommended
way?

basically im looking for best practices for handling object destruction.

Thanks
Justin
Sep 10 '07 #11
Darn. I have something wrong with my reader, I just noticed this has been
answered. Excuse the chaff.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
"Justin Rich" <jr******@yahoo.spam.comwrote in message
news:u7**************@TK2MSFTNGP04.phx.gbl...
so im trying to be good and not leave anything hanging open but i guess
ive seen a variety of ways to kill objects.. is there like a recommended
way?

basically im looking for best practices for handling object destruction.

Thanks
Justin
Sep 10 '07 #12
Sorry, IDisposable.

--
--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
"Justin Rich" <jr******@yahoo.spam.comwrote in message
news:u7**************@TK2MSFTNGP04.phx.gbl...
so im trying to be good and not leave anything hanging open but i guess
ive seen a variety of ways to kill objects.. is there like a recommended
way?

basically im looking for best practices for handling object destruction.

Thanks
Justin
Sep 10 '07 #13

"Tom Porterfield" <tp******@mvps.orgwrote in message
news:OR**************@TK2MSFTNGP06.phx.gbl...
Ben Voigt [C++ MVP] wrote:
>"Tom Porterfield" <tp******@mvps.orgwrote in message
>>Like most things, there is no one size fits all answer. If the object
is an object that connects to a resource, such as a SQL database, then
it likely has a close method that should be called. If the object in
its hierarchy implements IDisposable then you want to make sure its
Dispose method is called either explicitly or implicitly by creating the
object with the "using" keyword. If the object is just an RTW for an
unmanaged COM object then you'll want to properly release the underlying
come object, possibly with a call to Marshal.ReleaseComObject. It is
rare that I've seen setting the object to null to have a benefit.

Whether the actual cleanup action is Close, Flush, ReleaseComObject, or
whatever, nearly every object provides a Dispose method that "does the
right thing". If it implements IDisposable, call Dispose. Any other
cleanup requirement should be considered a bug.

A runtime callable wrapper is created whenever you interop to a COM
interface pointer from managed code. You should use
Marshal.ReleaseComObject to free the underlying COM object. Yes, you can
wait for the runtime to do this for you, just as you can wait for it to
dispose of an object that implements IDisposable, but that can lead to
memory issues. Having to call ReleaseComObject on a RCW is no more a bug
than needing to call Dispose on an IDisposable object.
RCW doesn't give you an interop smart pointer that implements IDisposable?
Yes, I would call that a bug. If you delete an ATL smart pointer the
IUnknown::Release method gets called. In .NET, things that own unmanaged
resources, and the reference count of a COM object is an unmanaged resource,
should provide a Dispose method to cleanup that native resource.

BTW the garbage collector won't dispose objects, it will only finalize them.
Failure to dispose IDisposable objects typically doesn't lead to memory
issues (shortage of memory just triggers a collection), it will lead to race
conditions on the unmanaged resource.
--
Tom Porterfield

Sep 10 '07 #14
Ben Voigt [C++ MVP] wrote:
[...]
BTW the garbage collector won't dispose objects, it will only finalize them.
Assuming a correctly implemented finalizer, what's the difference?
Isn't the finalizer supposed to dispose the object (at least with
respect to unmanaged resources), by calling Dispose with the appropriate
flag?
Failure to dispose IDisposable objects typically doesn't lead to memory
issues (shortage of memory just triggers a collection), it will lead to race
conditions on the unmanaged resource.
I also don't understand that comment, for a few somewhat unrelated reasons:

1) I don't know what sort of race conditions you're talking about.
What code is using the unmanaged resource in a way that is racing
with other code?

2) If the pressure is on unmanaged resources, I would expect
failure to dispose objects to not create the resource pressure that
would trigger a collection. You might get a collection for some other
reason, but if what you're running low on are unmanaged resources then,
by definition, the GC doesn't know about them and won't collect when you
run low.

So how does failure to dispose IDisposable objects consistently not
lead to memory issues, and if it doesn't and you aren't writing threaded
code, why is it still important to call Dispose?

And finally,

3) As the comment relates to your first one...if there's a
difference between finalization and disposing, why does triggering a
collection (assuming one is triggered) address the failure to dispose an
object?

Your comment may make sense to people who already know everything there
is to know about .NET memory management, but for me (and possibly others
in a similar position), I think there's some room for elaboration. :)

Thanks,
Pete
Sep 10 '07 #15

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:13************@corp.supernews.com...
Ben Voigt [C++ MVP] wrote:
>[...]
BTW the garbage collector won't dispose objects, it will only finalize
them.

Assuming a correctly implemented finalizer, what's the difference? Isn't
the finalizer supposed to dispose the object (at least with respect to
unmanaged resources), by calling Dispose with the appropriate flag?
I don't see the contradiction here. The GC does not call Dispose, that is
exactly why the object needs to properly cleanup the resources in the
finalizer as well as IDisposable.Dispose. If the garbage collector did
dispose objects, you'd hardly ever need a finalizer at all (and the managed
resources would be resurrected, promoted into the next generation).
>
>Failure to dispose IDisposable objects typically doesn't lead to memory
issues (shortage of memory just triggers a collection), it will lead to
race conditions on the unmanaged resource.

I also don't understand that comment, for a few somewhat unrelated
reasons:

1) I don't know what sort of race conditions you're talking about.
What code is using the unmanaged resource in a way that is racing with
other code?
Say you're writing a data file for batch processing. If you fail to dispose
the FileStream object, then when you trigger the process to read it, there's
a chance that it will fail because the file is still open by your
application. There's a race between the GC and the next process needing the
file.

Same goes for any other unmanaged resource, except memory. If you don't
explicitly commit the database transaction, your next query may not reflect
the new data. If you don't explicitly release the mutex, the next user may
fail to acquire it. If you don't explicitly close the socket, the TCP FIN
packet isn't sent to the remote end and his read() call may not complete.
Only memory is different, because (1) in almost every case, there is no
persistent reference, it is orphaned, so there isn't anyone waiting to
acquire it next and (2) when system memory runs low, the garbage collector
triggers and starts running finalizers.
>
2) If the pressure is on unmanaged resources, I would expect failure
to dispose objects to not create the resource pressure that would trigger
a collection. You might get a collection for some other reason, but if
what you're running low on are unmanaged resources then, by definition,
the GC doesn't know about them and won't collect when you run low.
That's true for everything but memory. The GC has to detect shortages of
system RAM and will trigger a collection.
>
So how does failure to dispose IDisposable objects consistently not
lead to memory issues, and if it doesn't and you aren't writing threaded
code, why is it still important to call Dispose?
For every resource but memory, it leads to a shortage that goes unnoticed by
the GC and isn't self-correcting.
>
And finally,

3) As the comment relates to your first one...if there's a difference
between finalization and disposing, why does triggering a collection
(assuming one is triggered) address the failure to dispose an object?
There is a difference, but as you already pointed out, properly designed
objects will free the unmanaged resource in either case.
>
Your comment may make sense to people who already know everything there is
to know about .NET memory management, but for me (and possibly others in a
similar position), I think there's some room for elaboration. :)

Thanks,
Pete

Sep 11 '07 #16
Bob Powell [MVP] <bo*@spamkillerbobpowell.netwrote:
If an object implements IDispose then call the Dispose method. If not then
set it's reference to null.
It's very rarely worth setting a variable to null. Most of the time you
don't gain anything - you just end up with more code which doesn't do
anything useful. There are a few exceptions, as Ben mentioned, but I'd
say I only manually "null out" a variable about once a month - if that!

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Sep 11 '07 #17
Peter Duniho wrote:
Ben Voigt [C++ MVP] wrote:
>[...]
BTW the garbage collector won't dispose objects, it will only finalize
them.

Assuming a correctly implemented finalizer, what's the difference? Isn't
the finalizer supposed to dispose the object (at least with respect to
unmanaged resources), by calling Dispose with the appropriate flag?
The difference is that when you do it yourself, you know when Dispose is
called. If you rely on the finalizer to do it, you don't know when it's
going to be called. Actually, there is no guarantee that the object is
ever going to be finalized.

--
Göran Andersson
_____
http://www.guffa.com
Sep 11 '07 #18
Göran Andersson wrote:
Peter Duniho wrote:
>Ben Voigt [C++ MVP] wrote:
>>[...]
BTW the garbage collector won't dispose objects, it will only
finalize them.

Assuming a correctly implemented finalizer, what's the difference?
Isn't the finalizer supposed to dispose the object (at least with
respect to unmanaged resources), by calling Dispose with the
appropriate flag?

The difference is that when you do it yourself, you know when Dispose is
called. If you rely on the finalizer to do it, you don't know when it's
going to be called. Actually, there is no guarantee that the object is
ever going to be finalized.
I'm aware of that. I should clarify: my question is in context of the
specific statement I quoted. That the "GC won't dispose objects". My
observation is that if the GC does finalize an object, it also disposes
it (assuming a correctly implemented finalizer).

It's true that finalization is different from disposal, and not even
guaranteed. But in the context of "the GC _ONLY_ finalizes an object"
(my emphasis, obviously), I have a problem with the statement. "ONLY
finalizing" implies that the GC is not disposing when it finalizes. But
assuming the finalizer was written correctly, IMHO that's the whole
point: for it to do the disposing that should have been done already.

In other words, the GC does implicitly wind up disposing, even though
that's not its job (and of course I agree it's not guaranteed...the
finalizer does need to be written correctly).

Pete
Sep 11 '07 #19
It's true that finalization is different from disposal, and not even
guaranteed. But in the context of "the GC _ONLY_ finalizes an object" (my
emphasis, obviously), I have a problem with the statement. "ONLY
finalizing" implies that the GC is not disposing when it finalizes. But
assuming the finalizer was written correctly, IMHO that's the whole point:
for it to do the disposing that should have been done already.

In other words, the GC does implicitly wind up disposing, even though
The GC gives the object a chance to dispose itself... which I argue is
different than having the GC dispose it, especially from the perspective of
the person designing the object.
Sep 12 '07 #20

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Bob Powell [MVP] <bo*@spamkillerbobpowell.netwrote:
>If an object implements IDispose then call the Dispose method. If not
then
set it's reference to null.

It's very rarely worth setting a variable to null. Most of the time you
don't gain anything - you just end up with more code which doesn't do
anything useful. There are a few exceptions, as Ben mentioned, but I'd
say I only manually "null out" a variable about once a month - if that!
I don't think I ever do. I sometimes call .Clear on a collection that's a
static member, such collections are usually marked readonly so they can't be
nulled anyway.

The important thing to know is that static members always provide
reachability.
Sep 12 '07 #21

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by lawrence | last post: by
5 posts views Thread by =?Utf-8?B?UGhpbCBKb2huc29u?= | last post: by
9 posts views Thread by =?Utf-8?B?YzY3NjIyOA==?= | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.