Dispose then set to nothing

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

I see in many MS example code that looks like this

Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this case?
Since myCustomer is a private variable, once it goes out of scope at the next
line, the reference to the object should be released.

Thanks.

Hao
 
Hao said:
Hi,

I see in many MS example code that looks like this

Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this case?
Since myCustomer is a private variable, once it goes out of scope at the next
line, the reference to the object should be released.

Thanks.

Hao

That is correct. Removing the reference is pointless in this case.
 
Hao Jiang said:
Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this case?

No, it actually isn't necessary for the reason you mentioned.
 
Hao Jiang,
As Göran & Herfried suggests setting myCustomer = Nothing is not needed for
the reason you give.

Instead of calling Dispose outright I would recommend using the new Using
statement in .NET 2.0 (VS 2005). The Using statement ensures that Dispose is
called even if one of the statements contained by the Using throws an
exception.
Public Sub Foo()
Using myCustomer as New Customer
... End Using
End Sub

Which is basically the following in .NET 1.x:

Dim myCustomer As New Customer
Try
DoSomething()
Finally
If myCustomer IsNot Nothing Then
myCustomer.Dispose()
End If
End Try
 
Hao Jiang,

Do you mean with MS samples, samples made by Micrsoft, if so can you than
show us some of those?
(URL's)

Because it is not correct, it is as
dim a as integer = 1 + 1
if a <> 2 then messagebox.show "there was a calculation error"

Thanks in advance,

Cor

Jay B. Harlow said:
Hao Jiang,
As Göran & Herfried suggests setting myCustomer = Nothing is not needed
for the reason you give.

Instead of calling Dispose outright I would recommend using the new Using
statement in .NET 2.0 (VS 2005). The Using statement ensures that Dispose
is called even if one of the statements contained by the Using throws an
exception.
Public Sub Foo()
Using myCustomer as New Customer
... End Using
End Sub

Which is basically the following in .NET 1.x:

Dim myCustomer As New Customer
Try
DoSomething()
Finally
If myCustomer IsNot Nothing Then
myCustomer.Dispose()
End If
End Try

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Hao Jiang said:
Hi,

I see in many MS example code that looks like this

Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this case?
Since myCustomer is a private variable, once it goes out of scope at the
next
line, the reference to the object should be released.

Thanks.

Hao
 
yeah; in vb6 when a variable went out of scope; it automagically
cleaned up after itself


except for DAO-- (which MS just ressurrected)
 
Thanks Goran, Hefried and Jay! That's what I thought.

Cor, please check out the 2nd and 3rd code section on this MS page:
http://support.microsoft.com/kb/888168

Hao

Cor Ligthert said:
Hao Jiang,

Do you mean with MS samples, samples made by Micrsoft, if so can you than
show us some of those?
(URL's)

Because it is not correct, it is as
dim a as integer = 1 + 1
if a <> 2 then messagebox.show "there was a calculation error"

Thanks in advance,

Cor

Jay B. Harlow said:
Hao Jiang,
As Göran & Herfried suggests setting myCustomer = Nothing is not needed
for the reason you give.

Instead of calling Dispose outright I would recommend using the new Using
statement in .NET 2.0 (VS 2005). The Using statement ensures that Dispose
is called even if one of the statements contained by the Using throws an
exception.
Public Sub Foo()
Using myCustomer as New Customer
... End Using
End Sub

Which is basically the following in .NET 1.x:

Dim myCustomer As New Customer
Try
DoSomething()
Finally
If myCustomer IsNot Nothing Then
myCustomer.Dispose()
End If
End Try

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Hao Jiang said:
Hi,

I see in many MS example code that looks like this

Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this case?
Since myCustomer is a private variable, once it goes out of scope at the
next
line, the reference to the object should be released.

Thanks.

Hao
 
Hi,

I see in many MS example code that looks like this

Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this case?
Since myCustomer is a private variable, once it goes out of scope at the next
line, the reference to the object should be released.

Thanks.

Hao

Hao,

To be absolutely precise the object is eligible for garbage collection
even before it goes out of scope as long as it's not used anymore. I
don't know how aggressive the GC rules are specifically, but it is
possible that the GC would consider the line myCustomer = Nothing as
having no side effects on the object and would collect the object even
before the line executed. I suppose it's reasonable to theorize that
the JIT compiler could optimize the line away as well.

Brian

Brian
 
Hao,

Thanks, I have sent it further

Cor

Hao Jiang said:
Thanks Goran, Hefried and Jay! That's what I thought.

Cor, please check out the 2nd and 3rd code section on this MS page:
http://support.microsoft.com/kb/888168

Hao

Cor Ligthert said:
Hao Jiang,

Do you mean with MS samples, samples made by Micrsoft, if so can you than
show us some of those?
(URL's)

Because it is not correct, it is as
dim a as integer = 1 + 1
if a <> 2 then messagebox.show "there was a calculation error"

Thanks in advance,

Cor

Jay B. Harlow said:
Hao Jiang,
As Göran & Herfried suggests setting myCustomer = Nothing is not needed
for the reason you give.

Instead of calling Dispose outright I would recommend using the new
Using
statement in .NET 2.0 (VS 2005). The Using statement ensures that
Dispose
is called even if one of the statements contained by the Using throws
an
exception.

Public Sub Foo()
Using myCustomer as New Customer
...
End Using
End Sub

Which is basically the following in .NET 1.x:

Dim myCustomer As New Customer
Try
DoSomething()
Finally
If myCustomer IsNot Nothing Then
myCustomer.Dispose()
End If
End Try

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Hi,

I see in many MS example code that looks like this

Public Sub Foo()
dim myCustomer as New Customer
...
myCustomer.Dispose()
myCustomer = Nothing
End Sub

I'm wondering if setting myCustomer = Nothing is necessary in this
case?
Since myCustomer is a private variable, once it goes out of scope at
the
next
line, the reference to the object should be released.

Thanks.

Hao
 
Brian,

It is completely inside the method, if the dispose is not there it goes out
of scoop and will be disposed because the method ends.

In my idea it is completely out of sense. (Not that I have the idea that you
have an opposite opinion).

Cor
 
Brian,

It is completely inside the method, if the dispose is not there it goes out
of scoop and will be disposed because the method ends.

In my idea it is completely out of sense. (Not that I have the idea that you
have an opposite opinion).

Cor

I'm not seeing how that's relevant. What I'm saying is that the
object is eligible for collection before the method returns and
possibly before it's variable reference is set to Nothing. And if
that's not true now then there's nothing in the CLI specification that
says a future version can't be that aggressive. Not only is setting
the reference to Nothing unnecessary, it could actually occur *after*
the memory has been released. That's something to consider in the
context of the OP's question.
 
Cor said:
It is completely inside the method, if the dispose is not there it goes out
of scoop and will be disposed because the method ends.

Just to be sure that it doesn't add to the confusion:

Removing the reference to an object and disposing an object are two
completely different things.
 
Removing the reference to an object and disposing an object are two
completely different things.

Yes going to the toilet and flush the toilet too, but here is an automatic
flushing system, a little bit strange to do it twice.

Cor,
 
Yes going to the toilet and flush the toilet too, but here is an automatic
flushing system, a little bit strange to do it twice.

Cor,

Cor,

I'm apologize in advance, I'm having a hard time understanding what
you're saying. How does your analogy relate to .NET. What's
happening twice? And how does the concept of disposing an object
relate to the OP's question?

To me anyway, the fact that the OP's question just happened to involve
an object that implements IDisposable was completely irrelevant.

Brian
 
Göran Andersson wrote:
Just to be sure that it doesn't add to the confusion:

Removing the reference to an object and disposing an object are two
completely different things.

Maybe this has little to do with the OP's question, but I wonder what
the impact would be for the following scenario:

<aircode>
Sub Bas()
'... code
'... code
If SomeCondition Then
Dim C(VeryHighNumberOfItems) As New SomeClass
'... code
'... code
End If
'... code
'... code
End Sub
</aircode>

In the pseudo-code above, even though the C array is declared inside
the If scope, VB defines the variable at Sub scope. Therefore, it
seems to me that the allocation will remain until the Sub exits...
Shouldn't C() be set to Nothing before leaving the If scope?

Regards,

Branco.
 
Branco,

Good question. See my responses inline.

Brian

Maybe this has little to do with the OP's question, but I wonder what
the impact would be for the following scenario:

<aircode>
Sub Bas()
'... code
'... code
If SomeCondition Then
Dim C(VeryHighNumberOfItems) As New SomeClass
'... code
'... code
End If
'... code
'... code
End Sub
</aircode>

In the pseudo-code above, even though the C array is declared inside
the If scope, VB defines the variable at Sub scope. Therefore, it
seems to me that the allocation will remain until the Sub exits...

As does C#. This can be verified by looking at the IL. So your
intuition would be that the memory is allocated for the duration of
the method. But, the GC is pretty smart and can recognize that the C
array is not used anymore outside of the If block. It is eligible for
collection before the remainder of the method executes.

This can cause a very confusing bug when using interop. If you pass
the array into a Win32 API call or something the GC could collect the
object even though the API may still be using it. That's why the
GC.KeepAlive method exists.
Shouldn't C() be set to Nothing before leaving the If scope?

It certainly wouldn't hurt, but it won't help either. Like I said the
GC will recognize that the array isn't used anymore anyway. And the
point I really wanted to drive home was that it is possible that array
could be collected even *before* the line that sets the reference to
Nothing is executed. I suspect in reality it's more likely that the
JIT compiler would just optimize the line away.
 
Brian Gideon said:
To me anyway, the fact that the OP's question just happened to involve
an object that implements IDisposable was completely irrelevant.

I agree. The advice that setting local variables to 'Nothing' at the end of
the procedure or one of its exit points applies to both classes implementing
'IDisposable' and classes not implementing this interface.
 
Branco said:
Göran Andersson wrote:


Maybe this has little to do with the OP's question, but I wonder what
the impact would be for the following scenario:

<aircode>
Sub Bas()
'... code
'... code
If SomeCondition Then
Dim C(VeryHighNumberOfItems) As New SomeClass
'... code
'... code
End If
'... code
'... code
End Sub
</aircode>

In the pseudo-code above, even though the C array is declared inside
the If scope, VB defines the variable at Sub scope. Therefore, it
seems to me that the allocation will remain until the Sub exits...
Shouldn't C() be set to Nothing before leaving the If scope?

Regards,

Branco.

There are memory allocated in two ways for that object, with different
life spans.

When the method is called, memory is allocated for the reference C in
the stack frame. This will remain allocated until the method returns and
the stack frame goes away.

When you create the array the memory for it is allocated on the heap.
This memory will remain in use until the last operation in the method
that uses it. Then it's up for garbage collection, and will eventually
be freed.

Eventhough the reference to the object remains in memory until the end
of the method, it's recognised that it's not used beyond the last actual
use of the object.

Clearing the reference will not shorten the time that the memory is in
use. It might in fact prolong the time slightly, if the clearing of the
reference would be considered the last use of the object instead of the
actual last use of the object. I don't know if the code analysis is
clever enough to distinguish between the different ways of using the
reference.
 
Cor said:
Yes going to the toilet and flush the toilet too, but here is an automatic
flushing system, a little bit strange to do it twice.

Cor,

Yes, an increase in temperature and a cow are also two different things,
and that doesn't have anything to do with what I said either.
 
Back
Top