By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,505 Members | 1,034 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,505 IT Pros & Developers. It's quick & easy.

Best Practice - Destroying objects

P: n/a
Hi,
I am after suggestions on the best practice declaring and destroying objects.

some example code:

Private Sub MySub

Dim frmMyForm As MyForm

Try

frmMyForm = New MyForm
frmMyForm.DoSomething

Catch ex As Exception
ProcessError(ex)
Finally
If Not frmMyForm Is Nothing Then
frmMyForm.Dispose()
frmMyForm = Nothing
End If
End Try
End Sub

I declare my object (form in this case) at the beginning of the routine.
I create it and us it.
Then I destroy it in the Finally section.

I use a Try Catch to capture and process any errors resulting from the use
of the form (or object).
I destroy the objects in the Finally section so that the code is run even if
there is an error. If it was in the main Try section it may not be run.

However if the logic is used in VB2008 I get a warning saying I am using a
variable before it is assigned a value.

How do I ensure I cater for unexpected errors?
How do I declare my objects?
Do I destroy them or simple let GC do it.?
Your opinions please



--
Tim
Sep 12 '08 #1
Share this Question
Share on Google+
41 Replies


P: n/a
On Sep 12, 8:40*am, Tim Marsden <tm...@newsgroup.nospamwrote:
Hi,
I am after suggestions on the best practice declaring and destroying objects.

some example code:

Private Sub MySub

* * Dim frmMyForm As MyForm *

* * Try

* * * *frmMyForm = New MyForm *
* * * *frmMyForm.DoSomething

* * *Catch ex As Exception
* * * *ProcessError(ex)
* * *Finally
* * * *If Not frmMyForm Is Nothing Then
* * * * * frmMyForm.Dispose()
* * * * * frmMyForm = Nothing
* * * *End If
* * End Try
End Sub

I declare my object (form in this case) at the beginning of the routine.
I create it and us it.
Then I destroy it in the Finally section.

I use a Try Catch to capture and process any errors resulting from the use
of the form (or object).
I destroy the objects in the Finally section so that the code is run evenif
there is an error. If it was in the main Try section it may not be run.

However if the logic is used in VB2008 I get a warning saying I am using a
variable before it is assigned a value.

How do I ensure I cater for unexpected errors?
How do I declare my objects?
Do I destroy them or simple let GC do it.?
Your opinions please

--
Tim *
For IDisposable objects, I recommend you dispose them whenever you
can. This topic is one of huge debate (Cor will be here shortly saying
the opposite of what I am) so I won't get into the why, but I'll
encourage you to search the archives for the discussions.

In your example, either of the below should work (I prefer the latter)

//////////////
Dim frmMyForm As MyForm = Nothing
Try
frmMyForm = New MyForm
frmMyForm.DoSomething
Catch ex As Exception
ProcessError(ex)
Finally
If Not frmMyForm Is Nothing Then
frmMyForm.Dispose()
frmMyForm = Nothing
End If
End Try
//////////////

//////////////
Try
Using frmMyForm As New MyForm()
frmMyForm.DoSomething()
End Using
Catch ex As Exception
ProcessError(ex)
End Try
//////////////

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/
Sep 12 '08 #2

P: n/a
On Sep 12, 7:40*am, Tim Marsden <tm...@newsgroup.nospamwrote:
Hi,
I am after suggestions on the best practice declaring and destroying objects.

some example code:

Private Sub MySub

* * Dim frmMyForm As MyForm *

* * Try

* * * *frmMyForm = New MyForm *
* * * *frmMyForm.DoSomething

* * *Catch ex As Exception
* * * *ProcessError(ex)
* * *Finally
* * * *If Not frmMyForm Is Nothing Then
* * * * * frmMyForm.Dispose()
* * * * * frmMyForm = Nothing
* * * *End If
* * End Try
End Sub
Setting frmMyForm = Nothing is pointless here since the variable has
local scope. In fact, the object referenced by frmMyForm is eligible
for collection before that line even executes. Of course, that is
assuming the CLR even executes it in first place since it may be
optimized out.
>
I declare my object (form in this case) at the beginning of the routine.
I create it and us it.
Then I destroy it in the Finally section.

I use a Try Catch to capture and process any errors resulting from the use
of the form (or object).
I destroy the objects in the Finally section so that the code is run evenif
there is an error. If it was in the main Try section it may not be run.

However if the logic is used in VB2008 I get a warning saying I am using a
variable before it is assigned a value.
Hmm...I'll have to double check the rules for definite assignment, but
I suspect the compiler is recognizing that the instantiation of MyForm
could throw an exception resulting in a usage of the variable in the
finally section before it is definitely assigned.
>
How do I ensure I cater for unexpected errors?
Use the 'using' construct.
How do I declare my objects?
Dim frmMyForm As MyForm = Nothing would have worked.
Do I destroy them or simple let GC do it.?
If an object implements IDisposable then it is recommened that you
always call Dispose.
Your opinions please

--
Tim *
Sep 12 '08 #3

P: n/a
Tim

Finaly, is only a part of a try catch block, where finaly means that it
always is done as long as the computer is not unplugged.

Setting the reference of an object to nothing is absolute without any sense
in VB after VB6, simple because it does nothing more then an instruction to
set a memory address to all zeroes. The object still stays at the managed
heap until it is removed by the Garbage Collector.

You are nowhere destroying any object in your code. You use dispose which as
Idispose is right implemtend releases all unmanaged resource used in your
object (as those are there). Dispose is a methode from components, while 20%
of the classes (especially controls) inherits that.

However, by instance in SharePoint and more classes, where the managed code
is only a wrapper around Com objects, it is adviced to use dispose to
release those unmanaged resources. If you are using SharePoint, then simple
invoke the dispose method to let the Idisposable section do its work.
Therefore it is by the SharePoint team called good practise to invoke
dispose at the end of every object (They have changed that text lately, it
is now more or less, good practise for Sharepoint objects).

Be aware that from the first day of managed code the dispose was seen as a
replacement for the deconstructor. In those days (and in non managed C++ but
not in Java) you should have used that deconstructor, therefore is in Java
and other managed languages like VB now the Garbage Collector. (And that is
in fact why it is called managed code). Some people started paroting, that
it was good practise to use Dispose as the method was in a class, the same
as it is with non managed code good practise to descruct every object. There
are tons of pages on Internet where people are only telling that it is good
practise, but never tell why (or something as it does not harm).

To destroy an object is possible by using the deconstructor. However, it is
strongly adviced not to do that and let the Garbage Collector do its work.

Have a look at the designer code of a form (it is in more wizards), there
you see the implementation of the IDispose which is done at every close of a
form. If you create yourform yourself, then you have to implement this code
as well yourself to have benefit from the dispose. If you use objects which
implements very much handles like pens, then it is aviced to use then
dispose (to release the handles) everytime before there the object is
nowhere referenced anymore (and that is not only its own reference, that one
does as I started with, in this case nothing).

Cor

"Tim Marsden" <tm***@newsgroup.nospamschreef in bericht
news:B2**********************************@microsof t.com...
Hi,
I am after suggestions on the best practice declaring and destroying
objects.

some example code:

Private Sub MySub

Dim frmMyForm As MyForm

Try

frmMyForm = New MyForm
frmMyForm.DoSomething

Catch ex As Exception
ProcessError(ex)
Finally
If Not frmMyForm Is Nothing Then
frmMyForm.Dispose()
frmMyForm = Nothing
End If
End Try
End Sub

I declare my object (form in this case) at the beginning of the routine.
I create it and us it.
Then I destroy it in the Finally section.

I use a Try Catch to capture and process any errors resulting from the use
of the form (or object).
I destroy the objects in the Finally section so that the code is run even
if
there is an error. If it was in the main Try section it may not be run.

However if the logic is used in VB2008 I get a warning saying I am using a
variable before it is assigned a value.

How do I ensure I cater for unexpected errors?
How do I declare my objects?
Do I destroy them or simple let GC do it.?
Your opinions please



--
Tim
Sep 13 '08 #4

P: n/a
Seth,

Is it possible to stop calling my name everytime in messages especialy as
you disagree with me?

Thanks,

Cor
"rowe_newsgroups" <ro********@yahoo.comschreef in bericht
news:1f**********************************@d45g2000 hsc.googlegroups.com...
On Sep 12, 8:40 am, Tim Marsden <tm...@newsgroup.nospamwrote:
Hi,
I am after suggestions on the best practice declaring and destroying
objects.

some example code:

Private Sub MySub

Dim frmMyForm As MyForm

Try

frmMyForm = New MyForm
frmMyForm.DoSomething

Catch ex As Exception
ProcessError(ex)
Finally
If Not frmMyForm Is Nothing Then
frmMyForm.Dispose()
frmMyForm = Nothing
End If
End Try
End Sub

I declare my object (form in this case) at the beginning of the routine.
I create it and us it.
Then I destroy it in the Finally section.

I use a Try Catch to capture and process any errors resulting from the use
of the form (or object).
I destroy the objects in the Finally section so that the code is run even
if
there is an error. If it was in the main Try section it may not be run.

However if the logic is used in VB2008 I get a warning saying I am using a
variable before it is assigned a value.

How do I ensure I cater for unexpected errors?
How do I declare my objects?
Do I destroy them or simple let GC do it.?
Your opinions please

--
Tim
For IDisposable objects, I recommend you dispose them whenever you
can. This topic is one of huge debate (Cor will be here shortly saying
the opposite of what I am) so I won't get into the why, but I'll
encourage you to search the archives for the discussions.

In your example, either of the below should work (I prefer the latter)

//////////////
Dim frmMyForm As MyForm = Nothing
Try
frmMyForm = New MyForm
frmMyForm.DoSomething
Catch ex As Exception
ProcessError(ex)
Finally
If Not frmMyForm Is Nothing Then
frmMyForm.Dispose()
frmMyForm = Nothing
End If
End Try
//////////////

//////////////
Try
Using frmMyForm As New MyForm()
frmMyForm.DoSomething()
End Using
Catch ex As Exception
ProcessError(ex)
End Try
//////////////

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/

Sep 13 '08 #5

P: n/a
On Sep 13, 1:17*am, "Cor Ligthert[MVP]" <notmyfirstn...@planet.nl>
wrote:
Tim

Finaly, is only a part of a try catch block, where finaly means that it
always is done as long as the computer is not unplugged.

Setting the reference of an object to nothing is absolute without any sense
in VB after VB6, simple because it does nothing more then an instruction to
set a memory address to all zeroes. The object still stays at the managed
heap until it is removed by the Garbage Collector.
It didn't make a whole lot of sense in VB6 either. When local
variables go out scope the object which was referenced had it's
reference count decremented anyway. Of course, you could force that
to happen sooner and in that respect it is a little different
situation.
You are nowhere destroying any object in your code. You use dispose whichas
Idispose is right implemtend releases all unmanaged resource used in your
object (as those are there). Dispose is a methode from components, while 20%
of the classes (especially controls) inherits that.

However, by instance in SharePoint and more classes, where the managed code
is only a wrapper around Com objects, *it is adviced to use dispose to
release those unmanaged resources. *If you are using SharePoint, then simple
invoke the dispose method to let the Idisposable section do its work.
Therefore it is by the SharePoint team called good practise to invoke
dispose at the end of every object (They have changed that text lately, it
is now more or less, good practise for Sharepoint objects).

Be aware that from the first day of managed code the dispose was seen as a
replacement for the deconstructor. In those days (and in non managed C++ but
not in Java) you should have used that deconstructor, therefore is in Java
and other managed languages like VB now the Garbage Collector. (And that is
in fact why it is called managed code). *Some people started paroting, that
it was good practise to use Dispose as the method was in a class, the same
as it is with non managed code good practise to descruct every object. There
are tons of pages on Internet where people are only telling that it is good
practise, but never tell why (or something as it does not harm).
It is a good practice because IDisposable *usually* implies that the
class holds unmanaged resources either directly or indirectly. Even
if the class didn't hold such resources it is still a good idea
because the class has basically warned you that they might add those
resources in the future.

By not calling Dispose you are relying on the GC to release the
resources when it runs the finalizers. The timing of that is
nondeterministic and be *very* problematic in a number of situations.
That is one reason why it is a good practice.
To destroy an object is possible by using the deconstructor. However, it is
strongly adviced not to do that and let the Garbage Collector do its work..

Have a look at the designer code of a form (it is in more wizards), there
you see the implementation of the IDispose which is done at every close of a
form. If you create yourform yourself, then you have to implement this code
as well yourself to have benefit from the dispose. If you use objects which
implements very much handles like pens, then it is aviced to use then
dispose (to release the handles) everytime before there the object is
nowhere referenced anymore (and that is not only its own reference, that one
does as I started with, in this case nothing).

Cor
Sep 13 '08 #6

P: n/a
Brian,

Microsoft will never use in future a method in a class in another way then
it is now.
(Or it should be a new overload addition, but that does not affect current
code)

Do you use constantly GetHasCode and ReferenceEquals by the way, in the way
you write should that be forever used, because it is in every class.

However, I can assure you that this does not implies that you should use it,
it are simple inherited methods like ToString.

However if you want to use it, feel free, but don't paroting the "It is good
practise sentence, to give more and more the idea that it is true". In
German history (that is not mine), there was a guy who did the same and was
able to let millions of persons to be killed.

Cor

"Brian Gideon" <br*********@yahoo.comschreef in bericht
news:1e**********************************@l42g2000 hsc.googlegroups.com...
On Sep 13, 1:17 am, "Cor Ligthert[MVP]" <notmyfirstn...@planet.nl>
wrote:
Tim

Finaly, is only a part of a try catch block, where finaly means that it
always is done as long as the computer is not unplugged.

Setting the reference of an object to nothing is absolute without any
sense
in VB after VB6, simple because it does nothing more then an instruction
to
set a memory address to all zeroes. The object still stays at the managed
heap until it is removed by the Garbage Collector.
It didn't make a whole lot of sense in VB6 either. When local
variables go out scope the object which was referenced had it's
reference count decremented anyway. Of course, you could force that
to happen sooner and in that respect it is a little different
situation.
You are nowhere destroying any object in your code. You use dispose which
as
Idispose is right implemtend releases all unmanaged resource used in your
object (as those are there). Dispose is a methode from components, while
20%
of the classes (especially controls) inherits that.

However, by instance in SharePoint and more classes, where the managed
code
is only a wrapper around Com objects, it is adviced to use dispose to
release those unmanaged resources. If you are using SharePoint, then
simple
invoke the dispose method to let the Idisposable section do its work.
Therefore it is by the SharePoint team called good practise to invoke
dispose at the end of every object (They have changed that text lately, it
is now more or less, good practise for Sharepoint objects).

Be aware that from the first day of managed code the dispose was seen as a
replacement for the deconstructor. In those days (and in non managed C++
but
not in Java) you should have used that deconstructor, therefore is in Java
and other managed languages like VB now the Garbage Collector. (And that
is
in fact why it is called managed code). Some people started paroting, that
it was good practise to use Dispose as the method was in a class, the same
as it is with non managed code good practise to descruct every object.
There
are tons of pages on Internet where people are only telling that it is
good
practise, but never tell why (or something as it does not harm).
It is a good practice because IDisposable *usually* implies that the
class holds unmanaged resources either directly or indirectly. Even
if the class didn't hold such resources it is still a good idea
because the class has basically warned you that they might add those
resources in the future.

By not calling Dispose you are relying on the GC to release the
resources when it runs the finalizers. The timing of that is
nondeterministic and be *very* problematic in a number of situations.
That is one reason why it is a good practice.
To destroy an object is possible by using the deconstructor. However, it
is
strongly adviced not to do that and let the Garbage Collector do its work.

Have a look at the designer code of a form (it is in more wizards), there
you see the implementation of the IDispose which is done at every close of
a
form. If you create yourform yourself, then you have to implement this
code
as well yourself to have benefit from the dispose. If you use objects
which
implements very much handles like pens, then it is aviced to use then
dispose (to release the handles) everytime before there the object is
nowhere referenced anymore (and that is not only its own reference, that
one
does as I started with, in this case nothing).

Cor
Sep 13 '08 #7

P: n/a
On Sep 13, 1:01*pm, "Cor Ligthert[MVP]" <notmyfirstn...@planet.nl>
wrote:
Brian,

Microsoft will never use in future a method in a class in another way then
it is now.
(Or it should be a new overload addition, but that does not affect current
code)

Do you use constantly GetHasCode and ReferenceEquals by the way, in the way
you write should that be forever used, because it is in every class.

However, I can assure you that this does not implies that you should use it,
it are simple inherited methods like ToString.

However if you want to use it, feel free, but don't paroting the "It is good
practise sentence, to give more and more the idea that it is true". In
German history (that is not mine), there was a guy who did the same and was
able to let millions of persons to be killed.

Cor
I don't know what to tell you that I haven't already in the past. If
a class implements IDisposable then assume it was put there for a
reason and call Dispose when you're done with it. The Framework
Design Guidelines book supports me on that point. I'd even rather see
someone do that across the board (i.e. DataSet) than not do it at all.
Sep 13 '08 #8

P: n/a
On 2008-09-13, Cor Ligthert[MVP] <no************@planet.nlwrote:
Tim

Finaly, is only a part of a try catch block, where finaly means that it
always is done as long as the computer is not unplugged.

Setting the reference of an object to nothing is absolute without any sense
in VB after VB6, simple because it does nothing more then an instruction to
set a memory address to all zeroes. The object still stays at the managed
heap until it is removed by the Garbage Collector.

You are nowhere destroying any object in your code. You use dispose which as
Idispose is right implemtend releases all unmanaged resource used in your
object (as those are there). Dispose is a methode from components, while 20%
of the classes (especially controls) inherits that.

However, by instance in SharePoint and more classes, where the managed code
is only a wrapper around Com objects, it is adviced to use dispose to
release those unmanaged resources. If you are using SharePoint, then simple
invoke the dispose method to let the Idisposable section do its work.
Therefore it is by the SharePoint team called good practise to invoke
dispose at the end of every object (They have changed that text lately, it
is now more or less, good practise for Sharepoint objects).

Be aware that from the first day of managed code the dispose was seen as a
replacement for the deconstructor. In those days (and in non managed C++ but
not in Java) you should have used that deconstructor, therefore is in Java
and other managed languages like VB now the Garbage Collector. (And that is
in fact why it is called managed code). Some people started paroting, that
it was good practise to use Dispose as the method was in a class, the same
as it is with non managed code good practise to descruct every object. There
are tons of pages on Internet where people are only telling that it is good
practise, but never tell why (or something as it does not harm).

To destroy an object is possible by using the deconstructor. However, it is
strongly adviced not to do that and let the Garbage Collector do its work.

Have a look at the designer code of a form (it is in more wizards), there
you see the implementation of the IDispose which is done at every close of a
form. If you create yourform yourself, then you have to implement this code
as well yourself to have benefit from the dispose. If you use objects which
implements very much handles like pens, then it is aviced to use then
dispose (to release the handles) everytime before there the object is
nowhere referenced anymore (and that is not only its own reference, that one
does as I started with, in this case nothing).

Cor

"Tim Marsden" <tm***@newsgroup.nospamschreef in bericht
news:B2**********************************@microsof t.com...
>Hi,
I am after suggestions on the best practice declaring and destroying
objects.

some example code:

Private Sub MySub

Dim frmMyForm As MyForm

Try

frmMyForm = New MyForm
frmMyForm.DoSomething

Catch ex As Exception
ProcessError(ex)
Finally
If Not frmMyForm Is Nothing Then
frmMyForm.Dispose()
frmMyForm = Nothing
End If
End Try
End Sub

I declare my object (form in this case) at the beginning of the routine.
I create it and us it.
Then I destroy it in the Finally section.

I use a Try Catch to capture and process any errors resulting from the use
of the form (or object).
I destroy the objects in the Finally section so that the code is run even
if
there is an error. If it was in the main Try section it may not be run.

However if the logic is used in VB2008 I get a warning saying I am using a
variable before it is assigned a value.

How do I ensure I cater for unexpected errors?
How do I declare my objects?
Do I destroy them or simple let GC do it.?
Your opinions please



--
Tim

--
Tom Shelton
Sep 14 '08 #9

P: n/a

"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:ur******************************@comcast.com. ..
>

--
Tom Shelton

Yep ;)

Sep 14 '08 #10

P: n/a
On 2008-09-14, Bill McCarthy <Bi**@localhost.comwrote:
>
"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:ur******************************@comcast.com. ..
>>

--
Tom Shelton


Yep ;)
LOL... It was a mispost.

--
Tom Shelton
Sep 14 '08 #11

P: n/a

"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:T5******************************@comcast.com. ..
On 2008-09-14, Bill McCarthy <Bi**@localhost.comwrote:
>>
"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:ur******************************@comcast.com ...
>>>

--
Tom Shelton


Yep ;)

LOL... It was a mispost.
<gYou should have said it was a practical demonstration: the post was set
to Nothing but there was still data there ;)

Sep 14 '08 #12

P: n/a
Guys,

Thanks for all your opinions it is very much appreciated. I am still a litle
confused. But to summarise:

Setting an object to nothing is NOT required.
Calling the dispose method is up for debate!
I am still unsure about using the Finally section to call the dispose to
ensure it is called if an error occurs.

Regards
Tim
Sep 14 '08 #13

P: n/a
On 2008-09-14, Tim Marsden <tm***@newsgroup.nospamwrote:
Guys,

Thanks for all your opinions it is very much appreciated. I am still a litle
confused. But to summarise:

Setting an object to nothing is NOT required.
That's right.
Calling the dispose method is up for debate!
Not really. Cor is about the only one I know who holds the opinion
that it shouldn't always be called. This not meant as disrespect to Cor.

Cor is correct, in there are objects where it is unnecessary. They get the
method by virtue of inheriting from component (such as DataSet) or some other
base class - yet, there is no way (other then looking at the source) to know
for sure. Further, you can never be sure that the implementation may change
in the future in such a way that the call is necessary.

The point being, it's better safe then sorry.
I am still unsure about using the Finally section to call the dispose to
ensure it is called if an error occurs.
Personally, I wouldn't do that if your using VB2005 or latter. Just wrap it
in a using statement. Using will ensure that Dispose is called, even if an
error occurs. I tend to write the code like this:

Try
Using o As New SomeDisposableObject()
o.DoCoolStuff()
End Using ' dispose always called - even if exception thrown
Catch e As Exception
' do stuff with exception
End Try

HTH

--
Tom Shelton
Sep 14 '08 #14

P: n/a
Tim Marsden wrote:
Guys,

Thanks for all your opinions it is very much appreciated. I am still
a litle confused. But to summarise:

Setting an object to nothing is NOT required.
Calling the dispose method is up for debate!
I am still unsure about using the Finally section to call the dispose
to ensure it is called if an error occurs.

Regards
Tim
In your original posted code, if you changed the Dim statement to
Dim frmMyForm As MyForm = Nothing
then you would be fine and have no warnings.

The Using statement is another useful way to ensure disposal, for instance with
modal dialog type forms:
Dim frmMyForm As New MyForm
Using frmMyForm
' ... all processing, including any try/catch blocks
End Using

You don't set an object to Nothing, you set a particular reference variable to
Nothing. It is possible to have a dozen different reference variables all
referring to the same object.

If a reference variable is declared local (within a method), it will go out of
scope and be set to Nothing at the end of the method. If it is declared at
module level, however, that is not true, and you may want to explicitly set it
to Nothing when appropriate.

The garbage collector will call Dispose methods on objects that require it, if
it has not already been called. This takes two cycles of collection to
completely release an object. If an object uses significant resources and is no
longer needed, it may take some time for collection to release those resources.
In those cases, it is useful to explicitly call Dispose, so your app isn't
hogging stuff it doesn't need. Rather than check every type to see how
significant it is, many adopt the strategy of disposing everything that can be
disposed of as soon as they are done with it.
Sep 14 '08 #15

P: n/a
Tom Shelton wrote:
I tend to write the code like this:

Try
Using o As New SomeDisposableObject()
o.DoCoolStuff()
End Using ' dispose always called - even if exception thrown
Catch e As Exception
' do stuff with exception
End Try
Hey Tom,

Do you think it matters whether you put a Try block within a Using block, or put
a Using block within a Try block? I tend to write it with the Try within the
Using, making the using object still in scope in the exception handler.
Sep 14 '08 #16

P: n/a
On Sun, 14 Sep 2008 11:39:01 -0700, Tim Marsden
<tm***@newsgroup.nospamwrote:
>Guys,

Thanks for all your opinions it is very much appreciated. I am still a litle
confused. But to summarise:

Setting an object to nothing is NOT required.
Calling the dispose method is up for debate!
I am still unsure about using the Finally section to call the dispose to
ensure it is called if an error occurs.

Regards
Tim
Setting a reference to an object to Nothing is not required if the
reference is about to go out of scope. If you have a form level
reference to something that is no longer needed, setting its reference
to Nothing makes it immediately available for garbage collection,
otherwise it will stay live until the form goes away.

If you use Using / End Using for disposable objects, they will be
disposed if anything goes wrong inside the Using block. Otherwise, if
you are going to allow a Try block to throw an exception then the
Finally clause should dispose anything local to the method that is
active that needs to be disposed.

I have seen a very good two part article on garbage collection on
msdn.microsoft.com, but I couldn't find it just now.

Sep 14 '08 #17

P: n/a
On Sun, 14 Sep 2008 12:45:50 -0700, "Steve Gerrard"
<my********@comcast.netwrote:

>The garbage collector will call Dispose methods on objects that require it, if
it has not already been called. This takes two cycles of collection to
completely release an object. If an object uses significant resources and is no
longer needed, it may take some time for collection to release those resources.
In those cases, it is useful to explicitly call Dispose, so your app isn't
hogging stuff it doesn't need. Rather than check every type to see how
significant it is, many adopt the strategy of disposing everything that can be
disposed of as soon as they are done with it.
To be strictly correct, the garbage collection does not call the
Dispose method. If the class has a Finalizer, it calls the Finalizer
method which normally will call the Dispose code.

Another good reason to call Dispose is that for classes with a
Finalizer, calling Dispose should mark the class as not needing its
Finalizer called. When the garbage collector calls Finalize it needs
two passes to fully dispose of the object, so preventing that frees
the object sooner and saves some overhead.

A few months ago I found a very good two part article on
msdn.microsoft.com about garbage collection, Dispose and Finalize, but
I looked just now and couldn't find it.
Sep 14 '08 #18

P: n/a
Jack Jackson wrote:
On Sun, 14 Sep 2008 12:45:50 -0700, "Steve Gerrard"
<my********@comcast.netwrote:

>The garbage collector will call Dispose methods on objects that

To be strictly correct, the garbage collection does not call the
Dispose method. If the class has a Finalizer, it calls the Finalizer
method which normally will call the Dispose code.
Yeah, that's what I meant. :)
Sep 14 '08 #19

P: n/a
On Sep 14, 2:56*pm, "Steve Gerrard" <mynameh...@comcast.netwrote:
Tom Shelton wrote:
I tend to write the code like this:
Try
Using o As New SomeDisposableObject()
* o.DoCoolStuff()
End Using ' dispose always called - even if exception thrown
Catch e As Exception
' do stuff with exception
End Try

Hey Tom,

Do you think it matters whether you put a Try block within a Using block,or put
a Using block within a Try block? I tend to write it with the Try within the
Using, making the using object still in scope in the exception handler.
I realize the question wasn't intended for me, but I'll answer
anyway. No, I don't think it matters. Do whatever is most
appropriate for the situation at hand. Often times that means not
taking advantage of try-catch blocks at all.
Sep 15 '08 #20

P: n/a
On 2008-09-14, Steve Gerrard <my********@comcast.netwrote:
Tom Shelton wrote:
>I tend to write the code like this:

Try
Using o As New SomeDisposableObject()
o.DoCoolStuff()
End Using ' dispose always called - even if exception thrown
Catch e As Exception
' do stuff with exception
End Try

Hey Tom,

Do you think it matters whether you put a Try block within a Using block, or put
a Using block within a Try block? I tend to write it with the Try within the
Using, making the using object still in scope in the exception handler.

Sure, you can do it that way :) Depends, if you need the object in scope,
then by all means.

--
Tom Shelton
Sep 15 '08 #21

P: n/a
Bill,

Good explanation of setting something to nothing

:-)

Cor

"Bill McCarthy" <Bi**@localhost.comschreef in bericht
news:u4**************@TK2MSFTNGP05.phx.gbl...
>
"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:T5******************************@comcast.com. ..
>On 2008-09-14, Bill McCarthy <Bi**@localhost.comwrote:
>>>
"Tom Shelton" <to*********@comcastXXXXXXX.netwrote in message
news:ur******************************@comcast.co m...
--
Tom Shelton
Yep ;)

LOL... It was a mispost.

<gYou should have said it was a practical demonstration: the post was
set to Nothing but there was still data there ;)
Sep 15 '08 #22

P: n/a
Jack,
If you use Using / End Using for disposable objects, they will be
disposed if anything goes wrong inside the Using block.
In my idea it is:

If you use Using/End Using for disposable objects, it means that the dispose
method is invoked at the end.
This will not mean that it will be removed. The Garbage Collector removes
only objects as there is nothing beside the own reference is referencing the
object.

Cor

Sep 15 '08 #23

P: n/a
On Sep 15, 1:41*am, "Cor Ligthert[MVP]" <notmyfirstn...@planet.nl>
wrote:
Jack,
If you use Using / End Using for disposable objects, they will be
disposed if anything goes wrong inside the Using block.

In my idea it is:

If you use Using/End Using for disposable objects, it means that the dispose
method is invoked at the end.
This will not mean that it will be removed. The Garbage Collector removes
only objects as there is nothing beside the own reference is referencing the
object.

Cor
Yes the GC will still have to remove the object, but it will remove
the object a generation early than when you just let the IDisposable
object fall out of scope (as the finalizer won't need to be called
since SupressFinalizer will be called). Also, since the object will be
collected sooner it will be removed faster (Gen0 collection generally
happen more often than Gen1) and will be less costly performance wise
(Gen0 collections are generally less expensive than Gen1). Not to
mention the fact that using Dispose will often remove unmanaged
resources, an immediate benefit for which the IDisposable pattern was
originally created for.

Also, the book "Improving .NET Application Performance and
Scalability: Patterns & Practices" by J.D. Meier, Srinath Vasireddy,
Ashish Babbar and Alex Mackma has a section devoted to the destruction
of objects and the IDisposable interface, and the authors agree that
you should always call Dispose on objects that implement IDisposable.
And if I remember correctly, this book was written from the internal
practices of Microsoft so that should give the book quite a bit of
credibility.

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/
Sep 15 '08 #24

P: n/a

Thanks for all the replies.

If I use the USING statement, do I still need to call the dispose method
before the END USING.

Tim
Sep 15 '08 #25

P: n/a
Hi Tim,

"Tim Marsden" <tm***@newsgroup.nospamwrote in message
news:53**********************************@microsof t.com...
Guys,

Thanks for all your opinions it is very much appreciated. I am still a
litle
confused. But to summarise:

Setting an object to nothing is NOT required.
Calling the dispose method is up for debate!
I am still unsure about using the Finally section to call the dispose to
ensure it is called if an error occurs.
Use Using blocks, but use them with care. For example, let's say you have
this code in a form:

Using br As Brush = Brushes.CadetBlue
Me.CreateGraphics.DrawString("hello world", Me.Font, br, 50,
200)
End Using

Seems okay and works *once*. The problem with it is it calls dispose on a
Shared member.

So the general rule is always call Dispose on types that implement
IDisposable (preferably by using Using blocks) with the exception of Shared
or Factory members where you need to consult the documentation to ensure it
won't cause issues (and/or test)

As to setting variables to Nothing, that only helps when you are talking
about fields. A special case is fields declared WithEvents, where setting
the reference to Nothing unwires any event handlers that are wired
declaratively via the Handles clause. In this case if the WithEvents
variable is Shared, you do need to set it to Nothing as otherwise it will
have a reference to your class, hence keeping your class alive (and events
firing).
Sep 15 '08 #26

P: n/a
On Sep 15, 7:29*am, Tim Marsden <tm...@newsgroup.nospamwrote:
Thanks for *all the replies.

If I use the USING statement, do I still need to call the dispose method
before the END USING.

Tim
Nope. The 'using' construct does that for you. When you get a chance
take a look at the resultant IL (via ILDASM or Reflector) to see how
it gets compiled.
Sep 15 '08 #27

P: n/a
Setting fields to nothing can be extremely useful when dealing with
shared members. Since shared properties have an extremely long
lifetime compared to other objects (usually the length of the
application) set them to nothing can preserve memory.

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/
Sep 15 '08 #28

P: n/a

"rowe_newsgroups" <ro********@yahoo.comwrote in message
news:d9**********************************@2g2000hs n.googlegroups.com...
Setting fields to nothing can be extremely useful when dealing with
shared members. Since shared properties have an extremely long
lifetime compared to other objects (usually the length of the
application) set them to nothing can preserve memory.

Thanks,
Huh ? Can you show me an example where that is the case ? Are you talking
about the type that exposes the Shared property, sure you could do that, but
in that case the Shared property would be returning multiple instances,
which could cause higher memory pressure in repeated calls.
For any consuming code, setting the instance to Nothing makes no difference
on a shared object: with the exception of WithEvents fields where you are
unwiring and hence releasing references to your consuming instance (aka a
circular reference where one node is Shared)

Sep 15 '08 #29

P: n/a
On Sep 15, 9:09*am, "Bill McCarthy" <B...@localhost.comwrote:
"rowe_newsgroups" <rowe_em...@yahoo.comwrote in message

news:d9**********************************@2g2000hs n.googlegroups.com...
Setting fields to nothing can be extremely useful when dealing with
shared members. Since shared properties have an extremely long
lifetime compared to other objects (usually the length of the
application) set them to nothing can preserve memory.
Thanks,

Huh ? *Can you show me an example where that is the case ? *Are you talking
about the type that exposes the Shared property, sure you could do that, but
in that case the Shared property would be returning multiple instances,
which could cause higher memory pressure in repeated calls.
For any consuming code, setting the instance to Nothing makes no difference
on a shared object: with the exception of WithEvents fields where you are
unwiring and hence releasing references to your consuming instance (aka a
circular reference where one node is Shared)
I think what Seth is trying to say can best expressed with the
following example.

Public Class A

Private m_Resource As Object = Nothing

Public Sub Open()
m_Resource = GetResource()
End Sub

Public Sub Close()
m_Resource = Nothing
End Sub

End Class

Since m_Resource is a field its reachability is dependent on the
lifetime of A. If we did not set m_Resource = Nothing in the Close
method its memory pressure would still be in play until A itself
became unreachable. This is a simple example demonstrating why
setting a field to Nothing can be useful. Notice that the field is
not even declared Shared.
Sep 15 '08 #30

P: n/a
Hi Brian,

"Brian Gideon" <br*********@yahoo.comwrote in message news:80**********************************@e53g2000 hsa.googlegroups.com...

The example you gave was a private field beign set to nothing not a Shared Property. For a private field setting it to nothing has no impact unless you expect the containing class to stay around a lot longer. For example, consider this code:

Module Module1

Sub Main()
Dim a As New A
a.Open()

a = Nothing

Console.WriteLine("press enter to cause GC to collect")
Console.ReadLine()

GC.Collect()

Console.WriteLine("press enter to exit")
Console.ReadLine()
End Sub

End Module
Class A

Private _b As B = Nothing

Public Sub Open()
_b = New B
End Sub

Protected Overrides Sub Finalize()
Console.WriteLine("A finalized")
End Sub
End Class
Class B

Protected Overrides Sub Finalize()
Console.WriteLine("B finalized")
End Sub
End Class

You will see with the single call to Collect both Finalizers are called. So the GC collection catches all objects that are not referenced from a rootable object. When you think about it it has to do this to deal with circular references. The setting of the field to Nothing has no practical effect unless you are keeping the containing instance alive.

As to Shared properties, like I said previously you can't set them to nothing as then the behavior is no longer like they are shared and hence you shift the memory pressure to creating new instances. If containing types set their reference to Nothing a Shared property by nature will still be in memory until the appdomain is unloaded.





Sep 15 '08 #31

P: n/a
On Sep 15, 11:17*am, "Bill McCarthy" <B...@localhost.comwrote:
Hi Brian,

"Brian Gideon" <briangid...@yahoo.comwrote in messagenews:80**********************************@e 53g2000hsa.googlegroups.com...

The example you gave was a private field beign set to nothing not a Shared Property. * For a private field setting it to nothing has no impact unless you expect the containing class to stay around a lot longer. For example, consider this code:

Module Module1

* * Sub Main()
* * * Dim a As New A
* * * a.Open()

* * * a = Nothing

* * * Console.WriteLine("press enter to cause GC to collect")
* * * Console.ReadLine()

* * * GC.Collect()

* * * Console.WriteLine("press enter to exit")
* * * Console.ReadLine()
* * End Sub

End Module

Class A

* *Private _b As B = Nothing

* *Public Sub Open()
* * * _b = New B
* *End Sub

* *Protected Overrides Sub Finalize()
* * * Console.WriteLine("A finalized")
* *End Sub
End Class

Class B

* *Protected Overrides Sub Finalize()
* * * Console.WriteLine("B finalized")
* *End Sub
End Class

You will see with the single call to Collect both Finalizers are called. *So the GC collection catches all objects that are not referenced from a rootable object. *When you think about it it has to do this to deal with circular references. The setting of the field to Nothing has no practical effect unless you are keeping the containing instance alive.

As to Shared properties, like I said previously you can't set them to nothing as then the behavior is no longer like they are shared and hence you shift the memory pressure to creating new instances. *If containing types set their reference to Nothing a Shared property by nature will still be inmemory until the appdomain is unloaded.
This conversation details one of the reasons I dislike using Shared
properties. As I understand, the problem is that shared properties
aren't unreachable until the application ends, as at any time the
shared property could be referenced and the value would need to be
returned. The other problem is that you don't know (without making
dangerous assumptions about architecture and design) when a shared
property isn't going to be used anymore.

Consider the following:

///////////
Private Shared _MyDataSet As DataSet

Public Shared Property MyDataSet() As DataSet
Get
Return _MyDataSet
End Get
Set (value As DataSet)
_MyDataSet = value
End Set
End Property
///////////

Suppose at one part of the application, the MyDataSet is filled by a
query such as "Select * From tbl_BiggestTableInDatabase". For the rest
of the application's lifetime (this shared property won't go out of
scope) you have this massive dataset stored in memory. It would be
beneficial to set this to nothing and remove the dataset, but like I
said earlier, you can never be certain that you will know when the
property is not being used.

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/
Sep 15 '08 #32

P: n/a

"rowe_newsgroups" <ro********@yahoo.comwrote in message
news:16**********************************@2g2000hs n.googlegroups.com...
>
>As to Shared properties, like I said previously you can't set them to
nothing as then the behavior is no longer like they are shared and
> >>hence you shift the memory pressure to creating new instances. If
containing types set their reference to Nothing a Shared property by
> >>nature will still be in memory until the appdomain is unloaded.

This conversation details one of the reasons I dislike using Shared
properties. As I understand, the problem is that shared properties
aren't unreachable until the application ends, as at any time the
shared property could be referenced and the value would need to be
returned. The other problem is that you don't know (without making
dangerous assumptions about architecture and design) when a shared
property isn't going to be used anymore.
Exactly. So you should generally not set shared properties to Nothing. You
should however consider carefully the design about having Shared properties
versus Shared functions

Sep 15 '08 #33

P: n/a
On Sep 15, 10:17*am, "Bill McCarthy" <B...@localhost.comwrote:
The setting of the field to Nothing has no practical effect unless you are keeping the containing instance alive.
That was my point. But, it works the same whether or not it is an
instance or shared field, except that the lifetime in the former is
dependent on the instance and later is dependent on the appdomain.
As to Shared properties, like I said previously you can't set them to nothing as then the behavior is no longer like they are shared and hence you shift the memory pressure to creating new instances. *If containing types set their reference to Nothing a Shared property by nature will still be inmemory until the appdomain is unloaded.
Hmm...I think I'm confused by the discussion of properties. If the
property takes the Nothing value and assigns it to shared reference
field then the object that was referenced by that field (assuming
there are no other references) will be eligible for collection
immediately. The result is that the memory allocated for the object
made available through the property could be reclaimed before the
appdomain ends. Obviously, I'm not understanding your point. Can you
explain a little more about what you mean?
Sep 15 '08 #34

P: n/a
On Sep 15, 11:47*am, "Bill McCarthy" <B...@localhost.comwrote:
"rowe_newsgroups" <rowe_em...@yahoo.comwrote in message

news:16**********************************@2g2000hs n.googlegroups.com...
As to Shared properties, like I said previously you can't set them to
nothing as then the behavior is no longer like they are shared and
*>>hence you shift the memory pressure to creating new instances. If
containing types set their reference to Nothing a Shared property by
*>>nature will still be in memory until the appdomain is unloaded.
This conversation details one of the reasons I dislike using Shared
properties. As I understand, the problem is that shared properties
aren't unreachable until the application ends, as at any time the
shared property could be referenced and the value would need to be
returned. The other problem is that you don't know (without making
dangerous assumptions about architecture and design) when a shared
property isn't going to be used anymore.

Exactly. *So you should generally not set shared properties to Nothing.*You
should however consider carefully the design about having Shared properties
versus Shared functions
My original comment was mainly aimed at the use of legacy code that
you have no control of. In many of those cases you may know when it is
safe to set the property to nothing and in that case it would be a
good idea.

This could be another good example for a class that implements
IDisposable. Suppose you must interact with a legacy code base that
makes (improper) use of shared properties. If your class fully
encapsulates the use of the legacy code through instance members, than
in the Dispose method you could safely set the legacy app's Shared
properties to nothing.

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/
Sep 15 '08 #35

P: n/a

"rowe_newsgroups" <ro********@yahoo.comwrote in message
news:3f**********************************@r66g2000 hsg.googlegroups.com...
If your class fully
encapsulates the use of the legacy code through instance members, than
in the Dispose method you could safely set the legacy app's Shared
properties to nothing.

No, definitely not. Again, go back to the first sample I posted (brushes)
and see the issues that causes.

Sep 15 '08 #36

P: n/a

"Brian Gideon" <br*********@yahoo.comwrote in message
news:61**********************************@e53g2000 hsa.googlegroups.com...
>Hmm...I think I'm confused by the discussion of properties. If the
property takes the Nothing value and assigns it to shared reference
field then the object that was referenced by that field (assuming
there are no other references) will be eligible for collection
immediately. The result is that the memory allocated for the object
made available through the property could be reclaimed before the
appdomain ends. Obviously, I'm not understanding your point. Can you
explain a little more about what you mean?
It no longer becomes shared. Again, look at the example around using shared
brushes. Or for another example, consider what happens with My.Forms.Form2
etc if you set that to Nothing : you force the disposing of the instance the
factory method exposes, hence closing that form regardless of what ever
other code thinks it had a valid reference. You cannot safely dispose
Shared resources as you don't know when there is no reference to them.
About the best you can do is expose the the property and use a WeakReference
as the backing field. That allows the GC to dispose of the resource (via
it's finalizer) if no other code is referencing it. If the reference is
still alive, you can pass on the target, if not re-instantiate. So again,
generally speaking you never set the actual resource to Nothing. Consuming
code can set their local references to Nothing, but never the actual Shared
resource or property.

Sep 15 '08 #37

P: n/a
On Sep 15, 12:38*pm, "Bill McCarthy" <B...@localhost.comwrote:
"Brian Gideon" <briangid...@yahoo.comwrote in message

news:61**********************************@e53g2000 hsa.googlegroups.com...
Hmm...I think I'm confused by the discussion of properties. *If the
property takes the Nothing value and assigns it to shared reference
field then the object that was referenced by that field (assuming
there are no other references) will be eligible for collection
immediately. *The result is that the memory allocated for the object
made available through the property could be reclaimed before the
appdomain ends. *Obviously, I'm not understanding your point. *Can you
explain a little more about what you mean?

It no longer becomes shared. Again, look at the example around using shared
brushes. *Or for another example, consider what happens with My.Forms.Form2
etc if you set that to Nothing : you force the disposing of the instance the
factory method exposes, hence closing that form regardless of what ever
other code thinks it had a valid reference. *You cannot safely dispose
Shared resources as you don't know when there is no reference to them.
About the best you can do is expose the the property and use a WeakReference
as the backing field. That allows the GC to dispose of the resource (via
it's finalizer) if no other code is referencing it. *If the reference is
still alive, you can pass on the target, if not re-instantiate. * So again,
generally speaking you never set the actual resource to Nothing. Consuming
code can set their local references to Nothing, but never the actual Shared
resource or property.
Okay, I'm totally with you now. Yes, you are exactly right. And I
see now why you were referring properties. If you make that resource
public (via a property or whatever) therein lies the problem. But, if
you keep that resource private then the containing class can make
better decisions on when to dispose it or set its field to nothing.
Again, I'm completely with you on that.
Sep 15 '08 #38

P: n/a
On Mon, 15 Sep 2008 23:08:21 +1000, "Bill McCarthy"
<Bi**@localhost.comwrote:
>Hi Tim,

"Tim Marsden" <tm***@newsgroup.nospamwrote in message
news:53**********************************@microso ft.com...
>Guys,

Thanks for all your opinions it is very much appreciated. I am still a
litle
confused. But to summarise:

Setting an object to nothing is NOT required.
Calling the dispose method is up for debate!
I am still unsure about using the Finally section to call the dispose to
ensure it is called if an error occurs.

Use Using blocks, but use them with care. For example, let's say you have
this code in a form:

Using br As Brush = Brushes.CadetBlue
Me.CreateGraphics.DrawString("hello world", Me.Font, br, 50,
200)
End Using

Seems okay and works *once*. The problem with it is it calls dispose on a
Shared member.
That code doesn't dispose the Graphics object.
Sep 15 '08 #39

P: n/a
No, definitely not. *Again, go back to the first sample I posted (brushes)
and see the issues that causes.
Good point.

I guess the strategy would then be to open up Reflector, see what
exactly is being used where and why, wrap the sucker in some unit
tests, and then set the properties to nothing if deemed a necessary
risk. Depending on the application, it might be worth the risk to set
public properties to nothing to conserve memory usage (long running
applications). In any case, the code in question would need to be
aggressively tested to help ensure it wouldn't go "kaboom" when
shipped to prod.

Anyways, this has turned into a very interesting discussion!

:-)

Thanks,

Seth Rowe [MVP]
http://sethrowe.blogspot.com/
Sep 15 '08 #40

P: n/a
"Tim Marsden" <tm***@newsgroup.nospamschrieb:
Thanks for all the replies.

If I use the USING statement, do I still need to call the dispose method
before the END USING.
No.

The call of 'Dispose' is guaranteed when using 'Using...End Using' (the
'Dispose' call is placed in a 'Finally' branch of a 'Try...Catch' block
under the hoods). The only way to prevent the call of 'Dispose' in a
'Using' block is to kill the process.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>

Sep 15 '08 #41

P: n/a

"Jack Jackson" <jj******@cinnovations.netwrote in message
news:m6********************************@4ax.com...
On Mon, 15 Sep 2008 23:08:21 +1000, "Bill McCarthy"
<Bi**@localhost.comwrote:
>>Hi Tim,

"Tim Marsden" <tm***@newsgroup.nospamwrote in message
news:53**********************************@micros oft.com...
>>Guys,

Thanks for all your opinions it is very much appreciated. I am still a
litle
confused. But to summarise:

Setting an object to nothing is NOT required.
Calling the dispose method is up for debate!
I am still unsure about using the Finally section to call the dispose to
ensure it is called if an error occurs.

Use Using blocks, but use them with care. For example, let's say you have
this code in a form:

Using br As Brush = Brushes.CadetBlue
Me.CreateGraphics.DrawString("hello world", Me.Font, br, 50,
200)
End Using

Seems okay and works *once*. The problem with it is it calls dispose on a
Shared member.

That code doesn't dispose the Graphics object.

Yes but that is not the issue I was demonstrating. The issue is the
disposing of the shared brush.


Sep 16 '08 #42

This discussion thread is closed

Replies have been disabled for this discussion.