Best Practice - Destroying objects

T

Tim Marsden

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
 
R

rowe_newsgroups

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

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/
 
B

Brian Gideon

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.
 
C

Cor Ligthert[MVP]

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
 
C

Cor Ligthert[MVP]

Seth,

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

Thanks,

Cor


"rowe_newsgroups" <[email protected]> schreef in bericht
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

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/
 
B

Brian Gideon

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.
 
C

Cor Ligthert[MVP]

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" <[email protected]> schreef in bericht
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.
 
B

Brian Gideon

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.
 
B

Bill McCarthy

Tom Shelton said:
LOL... It was a mispost.

<g> You should have said it was a practical demonstration: the post was set
to Nothing but there was still data there ;)
 
T

Tim Marsden

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
 
J

Jack Jackson

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.
 
J

Jack Jackson

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.
 
B

Brian Gideon

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.
 
C

Cor Ligthert[MVP]

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
 
R

rowe_newsgroups

Jack,


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/
 
T

Tim Marsden

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
 
B

Bill McCarthy

Hi Tim,

Tim Marsden said:
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).
 
B

Brian Gideon

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.
 

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

Similar Threads


Top