Home All Groups Group Topic Archive Search About

is an object destroyed/closed when an exception occurs

Author
4 Sep 2006 1:49 PM
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!

Author
4 Sep 2006 1:52 PM
Michael D. Ober
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.


<pugin***@gmail.com> wrote in message
Show quoteHide quote
news:1157377758.377260.265310@m79g2000cwm.googlegroups.com...
> 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!
>
>
Author
4 Sep 2006 2:21 PM
Robinson
Show quote Hide quote
"Michael D. Ober" <ober***@.alum.mit.edu.nospam> wrote in message
news:icWKg.6223$bM.4550@newsread4.news.pas.earthlink.net...
> 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
Author
4 Sep 2006 2:38 PM
Michael D. Ober
Good point - it didn't occur to me to check for the constructor throwing an
exception.

Mike.

Show quoteHide quote
"Robinson" <itoldyounottospamme@nowmyinboxisfull.com> wrote in message
news:edhcp2$ljv$1$8302bc10@news.demon.co.uk...
>
> "Michael D. Ober" <ober***@.alum.mit.edu.nospam> wrote in message
> news:icWKg.6223$bM.4550@newsread4.news.pas.earthlink.net...
> > 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
>
>
>
>
>
>
Author
4 Sep 2006 2:53 PM
Andrew Morton
Robinson wrote:
> 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
Author
5 Sep 2006 7:03 AM
puginews
Andrew Morton schreef:

Show quoteHide quote
> Robinson wrote:
> > 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

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!
Author
5 Sep 2006 7:18 AM
puginews
pugin***@gmail.com schreef:

Show quoteHide quote
> Andrew Morton schreef:
>
> > Robinson wrote:
> > > 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
>
> 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!
Author
5 Sep 2006 12:29 PM
Tom Shelton
pugin***@gmail.com wrote:
Show quoteHide quote
> Andrew Morton schreef:
>
> > Robinson wrote:
> > > 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
>
> 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,

--
Tom Shelton