try/finally with data access code

G

Guest

If I have code such a

SqConnection cndb = new SqlConnection(connstr)
SqlDataReader dr = null
tr

cndb.Open()
SqlCommand cmd = new SqlCommand("exec mysp", cndb)
dr = cmd.ExecuteReader()

catch (System.Exception e1) {Debug.WriteLine(e1.Message);
finall

if(dr != null) dr.Close()
cndb.Close()


what bugs me is that is there any possibility that dr would be non-null, but not open - when the finally block started - thus causing the lin
if(dr != null) dr.Close()
to fail, which would cause the cndb.Close() to never occur, leaving the connection open
This is in an ASP.NET page
Surely I don't have to put another try...finally within the first finally
or is there some property I can use to check the state of it

Thanks
Any suggestions please...
 
B

Bruno Jouhier [MVP]

No, dr cannot be null. ExecuteReader will throw an exception if it fails, it
will not return null.

You can simplify all this and rewrite it with the "using" statement because
all the objects that you manipulate implement the IDisposable interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you should
return a status indicating that the operation failed), I would not catch the
exception here? I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework) where it will be logged
and where the execution will resume.

Bruno.

RepStat said:
If I have code such as

SqConnection cndb = new SqlConnection(connstr);
SqlDataReader dr = null;
try
{
cndb.Open();
SqlCommand cmd = new SqlCommand("exec mysp", cndb);
dr = cmd.ExecuteReader();
}
catch (System.Exception e1) {Debug.WriteLine(e1.Message);}
finally
{
if(dr != null) dr.Close();
cndb.Close();
}

what bugs me is that is there any possibility that dr would be non-null,
but not open - when the finally block started - thus causing the line
 
B

Bonj

excellent, thanks!

Bruno Jouhier said:
No, dr cannot be null. ExecuteReader will throw an exception if it fails, it
will not return null.

You can simplify all this and rewrite it with the "using" statement because
all the objects that you manipulate implement the IDisposable interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you should
return a status indicating that the operation failed), I would not catch the
exception here? I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework) where it will be logged
and where the execution will resume.

Bruno.


but not open - when the finally block started - thus causing the line
 
B

bruce barker

you can repeatable call Close on a closed (or never opened) reader or
connection without error, so you need no more exception logic

-- bruce (sqlwork.com)


RepStat said:
If I have code such as

SqConnection cndb = new SqlConnection(connstr);
SqlDataReader dr = null;
try
{
cndb.Open();
SqlCommand cmd = new SqlCommand("exec mysp", cndb);
dr = cmd.ExecuteReader();
}
catch (System.Exception e1) {Debug.WriteLine(e1.Message);}
finally
{
if(dr != null) dr.Close();
cndb.Close();
}

what bugs me is that is there any possibility that dr would be non-null,
but not open - when the finally block started - thus causing the line
 
A

Angel Saenz-Badillos[MS]

This definitely gets my vote <g> when I think of all the trouble we could
have saved if we had written the docs in this fashion...
Unfortunately VB.net does not support the using construct and it still
requires try finally blocks.

Just one comment:
I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework)

Please not in the framework!
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.
 
B

Bruno Jouhier [MVP]

Angel Saenz-Badillos said:
This definitely gets my vote <g> when I think of all the trouble we could
have saved if we had written the docs in this fashion...
Unfortunately VB.net does not support the using construct and it still
requires try finally blocks.

Just one comment:

Please not in the framework!

Why not? In a WinForms app, if you do not catch exceptions in your event
handlers, the exceptions ends up being caught by the framework, which
triggers a ThreadException event. The default dialog box that the framework
displays is not the one I would like to see in a real application (I don't
want to give the option to kill the application, at least not in such a
visible way). So, the easiest way to handle all these exceptions it to let
the framework catch them and to associate a custom error dialog to the
ThreadException event. This way, you are sure that all exceptions will be
handled and reported in a consistent way.

There is one pitfall with this scheme, though: it does not work when the
application is run from the debugger, probably because the debugger
short-circuits the ThreadException event. This is a pain because the
application dies on the first exception when you run it from the debugger.
On the other hand, it works great when the application is run normally.

Bruno.
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.


Bruno Jouhier said:
No, dr cannot be null. ExecuteReader will throw an exception if it
fails,
it
will not return null.

You can simplify all this and rewrite it with the "using" statement because
all the objects that you manipulate implement the IDisposable interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you should
return a status indicating that the operation failed), I would not catch the
exception here? I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework) where it will be logged
and where the execution will resume.

Bruno.

"RepStat" <[email protected]> a écrit dans le message de
non-null,
but not open - when the finally block started - thus causing the line the
connection open?
 
M

Marcel

Bruno,

Can you give an example of how to catch the ThreadExeption? I want to use it
for any exeptions I fail to catch.
Will USING be in VB.NET 2005?

Marcel

Bruno Jouhier said:
Angel Saenz-Badillos said:
This definitely gets my vote <g> when I think of all the trouble we could
have saved if we had written the docs in this fashion...
Unfortunately VB.net does not support the using construct and it still
requires try finally blocks.

Just one comment:

Please not in the framework!

Why not? In a WinForms app, if you do not catch exceptions in your event
handlers, the exceptions ends up being caught by the framework, which
triggers a ThreadException event. The default dialog box that the framework
displays is not the one I would like to see in a real application (I don't
want to give the option to kill the application, at least not in such a
visible way). So, the easiest way to handle all these exceptions it to let
the framework catch them and to associate a custom error dialog to the
ThreadException event. This way, you are sure that all exceptions will be
handled and reported in a consistent way.

There is one pitfall with this scheme, though: it does not work when the
application is run from the debugger, probably because the debugger
short-circuits the ThreadException event. This is a pain because the
application dies on the first exception when you run it from the debugger.
On the other hand, it works great when the application is run normally.

Bruno.
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.


Bruno Jouhier said:
No, dr cannot be null. ExecuteReader will throw an exception if it
fails,
it
will not return null.

You can simplify all this and rewrite it with the "using" statement because
all the objects that you manipulate implement the IDisposable interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you should
return a status indicating that the operation failed), I would not
catch
the
exception here? I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework) where it will be logged
and where the execution will resume.

Bruno.

"RepStat" <[email protected]> a écrit dans le
message
 
B

Bruno Jouhier [MVP]

This is not an exception but an event sent by the framework. The syntax is:

Application.Exception += new ThreadExceptionEventHandler(exceptionProc);

Sorry, this is C#, I let you translate to VB because I am not fluent in VB
and I will probably mess it up.

You can take a look at the doc page on Application.ThreadException for more
details (and a VB example).

I am beta testing VS 2005 but I am only testing the J# and C# stuff. So, I
let someone else answer the VB question about "using". Seems to me that VB
should also support this very nice feature.

Bruno.

Marcel said:
Bruno,

Can you give an example of how to catch the ThreadExeption? I want to use it
for any exeptions I fail to catch.
Will USING be in VB.NET 2005?

Marcel

Bruno Jouhier said:
"Angel Saenz-Badillos[MS]" <[email protected]> a écrit dans le
message de news:[email protected]...
This definitely gets my vote <g> when I think of all the trouble we could
have saved if we had written the docs in this fashion...
Unfortunately VB.net does not support the using construct and it still
requires try finally blocks.

Just one comment:
I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework)

Please not in the framework!

Why not? In a WinForms app, if you do not catch exceptions in your event
handlers, the exceptions ends up being caught by the framework, which
triggers a ThreadException event. The default dialog box that the framework
displays is not the one I would like to see in a real application (I don't
want to give the option to kill the application, at least not in such a
visible way). So, the easiest way to handle all these exceptions it to let
the framework catch them and to associate a custom error dialog to the
ThreadException event. This way, you are sure that all exceptions will be
handled and reported in a consistent way.

There is one pitfall with this scheme, though: it does not work when the
application is run from the debugger, probably because the debugger
short-circuits the ThreadException event. This is a pain because the
application dies on the first exception when you run it from the debugger.
On the other hand, it works great when the application is run normally.

Bruno.
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.


No, dr cannot be null. ExecuteReader will throw an exception if it fails,
it
will not return null.

You can simplify all this and rewrite it with the "using" statement
because
all the objects that you manipulate implement the IDisposable interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you
should
return a status indicating that the operation failed), I would not catch
the
exception here? I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework) where it will be
logged
and where the execution will resume.

Bruno.

"RepStat" <[email protected]> a écrit dans le
message
de
If I have code such as

SqConnection cndb = new SqlConnection(connstr);
SqlDataReader dr = null;
try
{
cndb.Open();
SqlCommand cmd = new SqlCommand("exec mysp", cndb);
dr = cmd.ExecuteReader();
}
catch (System.Exception e1) {Debug.WriteLine(e1.Message);}
finally
{
if(dr != null) dr.Close();
cndb.Close();
}

what bugs me is that is there any possibility that dr would be non-null,
but not open - when the finally block started - thus causing the line
if(dr != null) dr.Close();
to fail, which would cause the cndb.Close() to never occur,
leaving
the
connection open?
This is in an ASP.NET page.
Surely I don't have to put another try...finally within the first
finally?
or is there some property I can use to check the state of it?

Thanks!
Any suggestions please...
 
M

Marcel

Thnx, does this event gets fired for all exceptions that are not catched by
your own code?

I don't have the beta version so i cannot find out for myself...

Marcel

Bruno Jouhier said:
This is not an exception but an event sent by the framework. The syntax is:

Application.Exception += new ThreadExceptionEventHandler(exceptionProc);

Sorry, this is C#, I let you translate to VB because I am not fluent in VB
and I will probably mess it up.

You can take a look at the doc page on Application.ThreadException for more
details (and a VB example).

I am beta testing VS 2005 but I am only testing the J# and C# stuff. So, I
let someone else answer the VB question about "using". Seems to me that VB
should also support this very nice feature.

Bruno.

Marcel said:
Bruno,

Can you give an example of how to catch the ThreadExeption? I want to
use
it
for any exeptions I fail to catch.
Will USING be in VB.NET 2005?

Marcel

Bruno Jouhier said:
"Angel Saenz-Badillos[MS]" <[email protected]> a écrit dans le
message de This definitely gets my vote <g> when I think of all the trouble we could
have saved if we had written the docs in this fashion...
Unfortunately VB.net does not support the using construct and it still
requires try finally blocks.

Just one comment:
I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework)

Please not in the framework!

Why not? In a WinForms app, if you do not catch exceptions in your event
handlers, the exceptions ends up being caught by the framework, which
triggers a ThreadException event. The default dialog box that the framework
displays is not the one I would like to see in a real application (I don't
want to give the option to kill the application, at least not in such a
visible way). So, the easiest way to handle all these exceptions it to let
the framework catch them and to associate a custom error dialog to the
ThreadException event. This way, you are sure that all exceptions will be
handled and reported in a consistent way.

There is one pitfall with this scheme, though: it does not work when the
application is run from the debugger, probably because the debugger
short-circuits the ThreadException event. This is a pain because the
application dies on the first exception when you run it from the debugger.
On the other hand, it works great when the application is run normally.

Bruno.
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.


No, dr cannot be null. ExecuteReader will throw an exception if it
fails,
it
will not return null.

You can simplify all this and rewrite it with the "using" statement
because
all the objects that you manipulate implement the IDisposable interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you
should
return a status indicating that the operation failed), I would not catch
the
exception here? I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework) where it will be
logged
and where the execution will resume.

Bruno.

"RepStat" <[email protected]> a écrit dans le message
de
If I have code such as

SqConnection cndb = new SqlConnection(connstr);
SqlDataReader dr = null;
try
{
cndb.Open();
SqlCommand cmd = new SqlCommand("exec mysp", cndb);
dr = cmd.ExecuteReader();
}
catch (System.Exception e1) {Debug.WriteLine(e1.Message);}
finally
{
if(dr != null) dr.Close();
cndb.Close();
}

what bugs me is that is there any possibility that dr would be
non-null,
but not open - when the finally block started - thus causing the line
if(dr != null) dr.Close();
to fail, which would cause the cndb.Close() to never occur, leaving
the
connection open?
This is in an ASP.NET page.
Surely I don't have to put another try...finally within the first
finally?
or is there some property I can use to check the state of it?

Thanks!
Any suggestions please...
 
B

Bruno Jouhier [MVP]

Marcel said:
Thnx, does this event gets fired for all exceptions that are not catched by
your own code?

I think so and so far it has worked this way. There is just one caveeat, as
I said in an earlier message: it won't work when your run your application
from the debugger, you have to run it "normally".
I don't have the beta version so i cannot find out for myself...

Marcel

Bruno Jouhier said:
This is not an exception but an event sent by the framework. The syntax is:

Application.Exception += new ThreadExceptionEventHandler(exceptionProc);

Sorry, this is C#, I let you translate to VB because I am not fluent in VB
and I will probably mess it up.

You can take a look at the doc page on Application.ThreadException for more
details (and a VB example).

I am beta testing VS 2005 but I am only testing the J# and C# stuff. So, I
let someone else answer the VB question about "using". Seems to me that VB
should also support this very nice feature.

Bruno.

Marcel said:
Bruno,

Can you give an example of how to catch the ThreadExeption? I want to
use
it
for any exeptions I fail to catch.
Will USING be in VB.NET 2005?

Marcel


"Angel Saenz-Badillos[MS]" <[email protected]> a écrit
dans
le
message de This definitely gets my vote <g> when I think of all the trouble we
could
have saved if we had written the docs in this fashion...
Unfortunately VB.net does not support the using construct and it still
requires try finally blocks.

Just one comment:
I would let it propagate upwards, until it reaches a
"strategic" point in your code (or in the framework)

Please not in the framework!

Why not? In a WinForms app, if you do not catch exceptions in your event
handlers, the exceptions ends up being caught by the framework, which
triggers a ThreadException event. The default dialog box that the
framework
displays is not the one I would like to see in a real application (I don't
want to give the option to kill the application, at least not in
such
a
visible way). So, the easiest way to handle all these exceptions it
to
let
the framework catch them and to associate a custom error dialog to the
ThreadException event. This way, you are sure that all exceptions
will
be
handled and reported in a consistent way.

There is one pitfall with this scheme, though: it does not work when the
application is run from the debugger, probably because the debugger
short-circuits the ThreadException event. This is a pain because the
application dies on the first exception when you run it from the debugger.
On the other hand, it works great when the application is run normally.

Bruno.
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.


No, dr cannot be null. ExecuteReader will throw an exception if it
fails,
it
will not return null.

You can simplify all this and rewrite it with the "using" statement
because
all the objects that you manipulate implement the IDisposable
interface.
Here is how I would rewrite this:

using (SqlConnection cndb = new SqlConnection(connstr))
{
cndb.Open();
using (SqlCommand cmd = new SqlCommand("exec mysp", cndb))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
// your stuff here
}
}
}

Also, unless you really want to log the exception at this level (you
should
return a status indicating that the operation failed), I would not
catch
the
exception here? I would let it propagate upwards, until it
reaches
a will
be
 

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

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top