is an object destroyed/closed when an exception occurs

  • Thread starter Thread starter puginews
  • Start date Start date
P

puginews

I was wondering when you create a new xmltextreader (or any other
object for that matter), is it destroyed/closed (memory/resources
freed) when an exception occurs ?

Dim xmlrdr As New XmlTextReader(Me.Server.MapPath("staff.xml"))
Try
Do While xmlrdr.Read()
Loop
xmlrdr.Close()
lblWellFormed.Text = "Well-Formed"
Catch ex As XmlException
lblWellFormed.Text = ex.Message
End Try

I don't do anything with the data I read, is just to test if it is
well-formed XML.
When staff.xml isn't well-formed an XMLException occurs.
Are the resources then freed like in xmlrdr.Close() ?
How can I test this ?
Or should I add a Finally to the try-catch and put xmlrdr.Close() in
the finally ?

thanx,

Pugi!
 
Only if the exception occurred after the xmlrdr.Close() statement. If it
occurs before that, it's left open. To ensure xmlrdr is always closed use
the following:

Dim xmlrdr As New XmlTextReader(Me.Server.MapPath("staff.xml"))
Try
Do While xmlrdr.Read()
Loop
lblWellFormed.Text = "Well-Formed"

Catch ex As XmlException
lblWellFormed.Text = ex.Message

Finally
xmlrdr.Close()
End Try

Mike Ober.
 
Michael D. Ober said:
Only if the exception occurred after the xmlrdr.Close() statement. If it
occurs before that, it's left open. To ensure xmlrdr is always closed use
the following:

Dim xmlrdr As New XmlTextReader(Me.Server.MapPath("staff.xml"))
Try
Do While xmlrdr.Read()
Loop
lblWellFormed.Text = "Well-Formed"

Catch ex As XmlException
lblWellFormed.Text = ex.Message

Finally
xmlrdr.Close()
End Try

Mike Ober.


True but unfortunately you have opened the reader outside of the try/catch
and it's constructor could throw..... ;)


Dim xmlrdr As XmlTextReader

Try

xmlrdr = new XmlTextReader (Me.Server.MapPath("staff.xml"))

Do While xmlrdr.Read()

Loop

lblWellFormed.Text = "Well-Formed"

Catch ex As XmlException

lblWellFormed.Text = ex.Message

Finally

xmlrdr.Close()

End Try
 
Good point - it didn't occur to me to check for the constructor throwing an
exception.

Mike.
 
Robinson said:
True but unfortunately you have opened the reader outside of the
try/catch and it's constructor could throw..... ;)

But then surely trying to .close() the XML reader would throw?
Dim xmlrdr As XmlTextReader
Try
xmlrdr = new XmlTextReader (Me.Server.MapPath("staff.xml"))
Do While xmlrdr.Read()
Loop
lblWellFormed.Text = "Well-Formed"
Catch ex As XmlException
lblWellFormed.Text = ex.Message
Finally
xmlrdr.Close()
End Try

So wouldn't it need

Finally
If Not (xmlrdr Is Nothing) Then
xmlrdr.Close()
End If
End Try

?

Andrew
 
Andrew Morton schreef:
But then surely trying to .close() the XML reader would throw?


So wouldn't it need

Finally
If Not (xmlrdr Is Nothing) Then
xmlrdr.Close()
End If
End Try

?

Andrew

Nice, but the moment the code 'Dim xmlrdr As XmlTextReader' gets
executed, which is allways, xmlrdr is 'something', so Not (xmlrdr Is
Nothing) will allways return true. So the if statement in the finally
block is useless. Unless there is a way to test if any resources have
been allocated to this object. Is Nothing test wether an object exists,
not for allocated resources.
If the file doesn't exist, it will throw an exception different from
XmlException. So for the moment, the code looks like this:

Dim xmlrdr As XmlTextReader
Try
xmlrdr = New XmlTextReader(Me.Server.MapPath("staff.xml"))
Do While xmlrdr.Read
Loop
lblWellFormed.Text = "Well-Formed"
Catch ex As XmlException
lblWellFormed.Text = "XML : " & ex.Message
Catch ex As Exception
lblWellFormed.Text = "Other : " & ex.Message
Finally
xmlrdr.Close()
End Try

In the case that staff.xml does not exist, the other exception catches
it, and closing xmlrdr ,while no resources have been allocated, doesn't
result in a new exception.

Pugi!
 
(e-mail address removed) schreef:
Andrew Morton schreef:


Nice, but the moment the code 'Dim xmlrdr As XmlTextReader' gets
executed, which is allways, xmlrdr is 'something', so Not (xmlrdr Is
Nothing) will allways return true. So the if statement in the finally
block is useless. Unless there is a way to test if any resources have
been allocated to this object. Is Nothing test wether an object exists,
not for allocated resources.
If the file doesn't exist, it will throw an exception different from
XmlException. So for the moment, the code looks like this:

Dim xmlrdr As XmlTextReader
Try
xmlrdr = New XmlTextReader(Me.Server.MapPath("staff.xml"))
Do While xmlrdr.Read
Loop
lblWellFormed.Text = "Well-Formed"
Catch ex As XmlException
lblWellFormed.Text = "XML : " & ex.Message
Catch ex As Exception
lblWellFormed.Text = "Other : " & ex.Message
Finally
xmlrdr.Close()
End Try

In the case that staff.xml does not exist, the other exception catches
it, and closing xmlrdr ,while no resources have been allocated, doesn't
result in a new exception.

Pugi!

Sorry, the above code will work nicely. But the moment I place code in
the try-block before the statement 'xmlrdr = New
XmlTextReader(Me.Server.MapPath("staff.xml"))' and an exception occurs
before the mentioned statment, closing the reader throws a new
exception in the finally block.

I think this code should do it :

Dim xmlrdr As XmlTextReader = Nothing
Try
' if some code here throws an exception before next
statement is executed, xmlrdr Is Nothing
xmlrdr = New XmlTextReader(Me.Server.MapPath("staff.xml"))
Do While xmlrdr.Read
Loop
lblWellFormed.Text = "Well-Formed"
Catch ex As XmlException
lblWellFormed.Text = "XML : " & ex.Message
Catch ex As Exception
lblWellFormed.Text = "Other : " & ex.Message
Finally
If Not (xmlrdr Is Nothing) Then
xmlrdr.Close()
End If
End Try

I guess this wraps it up, unless anyone has some suggestions ?

Thanx for the replies.

Pugi!
 
Andrew Morton schreef:


Nice, but the moment the code 'Dim xmlrdr As XmlTextReader' gets
executed, which is allways, xmlrdr is 'something', so Not (xmlrdr Is
Nothing) will allways return true.

Nope. If the constructor throws, then the object is nothing. The code
prevents a null reference exception in the finally block.

Module Module1

Sub Main()
Dim a As ThrowAnException
Try
a = New ThrowAnException()
Catch ex As Exception
If a Is Nothing Then Console.WriteLine("It's nothing!")
Console.WriteLine(ex.Message)
End Try
End Sub

Class ThrowAnException
Public Sub New()
Throw New Exception("We threw!")
End Sub
End Class
End Module

HTH,
 
Back
Top