call functions that return MemoryStream or XmlDocument

  • Thread starter Thread starter Atara
  • Start date Start date
A

Atara

Suppose I have the following functions:

Public Function myF1ToStream(...) As System.IO.MemoryStream
. . .
Dim ms As New System.IO.MemoryStream(buf)
Return ms
End Function

Public Function mcF2ToXml(. . .) As Xml.XmlDocument
. . .
Dim xmlDoc As New Xml.XmlDocument
xmlDoc.Load(ms)
Return xmlDoc
End Function


When I call these functions, which of the following lines marked with
('?) is necessary?
(I use vs2003, without 'Using' keyword. )

Dim ms As System.IO.MemoryStream = myF1ToStream(...)
'? ms.Seek(0, System.IO.SeekOrigin.Begin)
. . . ms.ReadByte() . . .
'? ms.Close()
'? ms = Nothing

Dim xmlDoc As XmlDocument = mcF2ToXml(...)
. . . myUse(xmlDoc) . . .
'? xmlDoc = Nothing

Thanks,

Atara
 
Atara,

I never used the seek in a memorystream, I always start at zero, so I don't
know if it in your case is necessary.

Setting something to nothing means only that it removes the reference, so
"you" can not direct use it anymore.

However that does not mean that it does not exist anymore, therefore it is a
little bit without sense.

Because it is asked so often, I have made this little piece of sample to
show it.

Drag for this a DataGridView and a Button on a form paste in this code and
run it.
\\\
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim dt As New DataTable
Dim dc As New DataColumn("a", GetType(System.String))
dt.Columns.Add(dc)
dc.Dispose()
dc = Nothing
For i = 1 To 5
Dim dr As DataRow = dt.NewRow
dr.Item(0) = i.ToString
dt.Rows.Add(dr)
Next
DataGridView1.DataSource = dt
dt.Dispose()
dt = Nothing

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim dt As DataTable = DirectCast(DataGridView1.DataSource, DataTable)
For i = 6 To 10
Dim dr As DataRow = dt.NewRow
dr.Item(0) = i.ToString
dt.Rows.Add(dr)
Next
End Sub
///

Cor
 
I did not understand your code sample - do I need to dispose the
returned memoryStream, and the returned xmlDocument when I am done with
them?

I never so a sample code of returning such types from a function. In
sample code, this types are always used within one function (so I guess
that when the function ends its memory is collected)

thanks,

Atara
 
Atara,

Did you run the sample, I have put direct the dispose in it, because that
gives mostly the same misunderstandings as the nothing.

Try it and it should becoume clear.

You don't have to set in these situations something to nothing or to use the
dispose method. Simple because it takes only processing time and has not any
effect.

Cor
 
Suppose I have the following functions:

Public Function myF1ToStream(...) As System.IO.MemoryStream
. . .
Dim ms As New System.IO.MemoryStream(buf)
Return ms
End Function

Public Function mcF2ToXml(. . .) As Xml.XmlDocument
. . .
Dim xmlDoc As New Xml.XmlDocument
xmlDoc.Load(ms)
Return xmlDoc
End Function


When I call these functions, which of the following lines marked with
('?) is necessary?
(I use vs2003, without 'Using' keyword. )

Dim ms As System.IO.MemoryStream = myF1ToStream(...)
'? ms.Seek(0, System.IO.SeekOrigin.Begin)
. . . ms.ReadByte() . . .
'? ms.Close()
'? ms = Nothing

Dim xmlDoc As XmlDocument = mcF2ToXml(...)
. . . myUse(xmlDoc) . . .
'? xmlDoc = Nothing

Thanks,

Atara

I don't see how this one would be needed:
'? ms.Seek(0, System.IO.SeekOrigin.Begin)

You need to either call Close or Dispose to release resources.
'? ms.Close()
Otherwise the resources won't be released until the object is garbage
collected, which might not be for a long time.

Setting a reference to Nothing is rarely needed if the variable has a
local scope. If 'ms' will go out of scope very soon, then there is no
reason to set it to Nothing.
'? ms = Nothing
'? xmlDoc = Nothing
Same as above. If 'xmlDoc' will soon go out of scope, there is no
need. If 'xmlDoc' has a long life (e.g. Form property) then you
should set it to Nothing.

Removing all references to an object, either because the referencing
variable goes out of scope (gets destroyed) or because it is set to
Nothing, does not cause anything to happen immediately, it just makes
the object available for garbage collection.
 
Jack,

snip,
Removing all references to an object, either because the referencing
variable goes out of scope (gets destroyed) or because it is set to
Nothing, does not cause anything to happen immediately, it just makes
the object available for garbage collection.
snip

I tried to show with my sample that the latter part of this is only true, if
the object is not referenced anymore by any other object.

Cor
 
Please correct me if I mis-understood you:

1. Regarding the memoryStream, if f1() returns memoryStream, and f2()
uses it, (and it can happen 1000 times during my program,) I better
close the memoryStream, so it will be garbage-collected soon, but I do
not have to set it to Nothing???

Public Sub f2()
Dim ms As System.IO.MemoryStream = f1(...)
. . . ms.ReadByte() . . .
ms.Close()
End Sub

2. Regarding the xmlDocument - how do I force it to be garbage-collected
as soon as it is not used?
(at the beginning of my program, I read ~40 xml files, their total file
size is ~8M, but when creating from each xml file xmlDocument object, I
guess their size is larger)

Thanks,

Atara.

Thanks,

Atara.
 
1. Regarding the memoryStream, if f1() returns memoryStream, and f2()
uses it, (and it can happen 1000 times during my program,) I better
close the memoryStream, so it will be garbage-collected soon, but I do
not have to set it to Nothing???
Correct

Public Sub f2()
Dim ms As System.IO.MemoryStream = f1(...)
. . . ms.ReadByte() . . .
ms.Close()
End Sub

2. Regarding the xmlDocument - how do I force it to be garbage-collected
as soon as it is not used?
(at the beginning of my program, I read ~40 xml files, their total file
size is ~8M, but when creating from each xml file xmlDocument object, I
guess their size is larger)
Set them simple in a method, as soon as that goes out of scope and there is
no reference anymore to it from somewhere else, it simply is in the normal
procedure to be garbaged as soon as this is needed.

Forcing the GC has never been a success and as long as there is any
reference to an object, it is only doing a costly job in not wanted time.

Cor
 
Before I be misunderstood, each read in a method where the instancing is
done in that method.

Cor
 
Please correct me if I mis-understood you:

1. Regarding the memoryStream, if f1() returns memoryStream, and f2()
uses it, (and it can happen 1000 times during my program,) I better
close the memoryStream, so it will be garbage-collected soon, but I do
not have to set it to Nothing???

You need to call Close, but not so that it will be garbage collected
soon. Calling Close has no effect on garbage collection. You need to
call Close so that the object will release any resources it is
holding.
Public Sub f2()
Dim ms As System.IO.MemoryStream = f1(...)
. . . ms.ReadByte() . . .
ms.Close()
End Sub

2. Regarding the xmlDocument - how do I force it to be garbage-collected
as soon as it is not used?
(at the beginning of my program, I read ~40 xml files, their total file
size is ~8M, but when creating from each xml file xmlDocument object, I
guess their size is larger)

Once there is no longer a reference to the object, either because you
set the reference to Nothing or because the reference went out of
scope, the object is eligible for garbage collection. You could force
a garbage collection, but that is very bad practice. Just let the
garbage collector run when it determines it needs to run.
 
Back
Top