Question

  • Thread starter Thread starter Roy
  • Start date Start date
R

Roy

What is the correct sequence for 'using' statement and 'try -- catch'? Which
of the following is right?

try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
send some queries to db
}
}
catch (Exeption e)
{
handle exception
}

Or

using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
send some queries to db
}
catch (Exeption e)
{
handle exception
}
}
 
Actually the first thing 'do some queries' will do is open the connection and
then issue several queries. So in normal case the connection object will be
disposed after that.

My question is if any of those will leave any resource un-released in both
cases?
 
Actually the first thing 'do some queries' will do is open the
connection and
then issue several queries. So in normal case the connection object will
be
disposed after that.

That's not an answer to Scott's question. What happens in the normal case
isn't relevant to what he asked.
My question is if any of those will leave any resource un-released in
both
cases?

Impossible to answer, as you haven't provided a complete code sample
showing everything that might be created within the code. However, we can
confirm that in either arrangement, no resource associated with the new
SqlConnection instance will be left undisposed.

The other main difference between the two arrangements you posted is, in
addition to the question of where the "connection" variable is available,
that if creating the connection itself throws an exception, it would not
be caught in the second version, but would be caught in the first.

Which arrangement you would use depends on those two specific differences,
and how you need the code to behave.

Pete
 
No. The order won't matter in those terms. Using "Using" simply calls
dispose() on the connection when the end of the block is hit.
 
The other main difference between the two arrangements you posted is, in
addition to the question of where the "connection" variable is available,
that if creating the connection itself throws an exception, it would not
be caught in the second version, but would be caught in the first.

Technically true, but in reality, the only way that the code that creates
the instance could fail would be caught @ compile time, rather than run time
since that act of creating an instance of this class and passing a
connection string could not throw a run-time exception. With that in mind,
neither case would be better than the other at catching run-time exception.

-Scott
 
Technically true, but in reality, the only way that the code that creates
the instance could fail would be caught @ compile time, rather than run
time
since that act of creating an instance of this class and passing a
connection string could not throw a run-time exception.

I don't know why you say that. At the very least, an out-of-memory
exception is _always_ a possibility when constructing a new instance of an
object.

Now, it may be that one does not care about such an exception. It's
fairly common to see programs where no exception handling is done with
respect to instantiating new objects. Probably more common than those
that do handle OOM situations.

But that's not the same as saying it can't happen.

Pete
 
Using that logic, one should have absolutely everything that uses memory in
a Try...Catch, even local variable declarations, which is unreasonable.

The fact remains that, from a coding point of view, putting the
instantiation of a connection in a Try...Catch does not serve any practical
purpose.
 
Using that logic, one should have absolutely everything that uses memory
in
a Try...Catch, even local variable declarations, which is unreasonable.

Local variable declarations don't allocate memory. Maybe you are thinking
of the possibility of a stack overflow exception, but a) you would have to
wrap the calls with try/catch to get those, and b) you can design your
code to easily avoid those, which is not the case for out-of-memory
exceptions.
The fact remains that, from a coding point of view, putting the
instantiation of a connection in a Try...Catch does not serve any
practical
purpose.

Of course it does. At least for those people who wish to write
applications that don't just crash when memory is restricted.

Your mileage may vary, but it's poor practice for any serious application
to crash, under any circumstances. Including low-memory conditions. If
you don't want to write serious applications, that's fine, but that
doesn't make your generalization about "does not serve any practical
purpose" true. Don't make the mistake of thinking that just because you
don't find something useful, no one does.

Pete
 
[...]
Your mileage may vary, but it's poor practice for any serious
application to crash, under any circumstances. Including low-memory
conditions. If you don't want to write serious applications, that's
fine, but that doesn't make your generalization about "does not serve
any practical purpose" true. Don't make the mistake of thinking that
just because you don't find something useful, no one does.

And lest you misunderstand me: it is perfectly reasonable to catch
out-of-memory exceptions higher up. I am taking issue with your
implication that no one need concern themselves with out-of-memory
exceptions at all.

Pete
 
Scott and Peter:
Are you saying that:
In the 1st case ('using' inside a 'try'), the connection object will be
disposed before executing 'catch'?
In the 2nd case ('try' inside 'using'), the connection object will be
disposed too even I decide to exit from the function in catch?

Thanks.
Roy
 
Scott and Peter:
Are you saying that:
In the 1st case ('using' inside a 'try'), the connection object will be
disposed before executing 'catch'?

Yes. Assuming an exception occurs, of course. If no exception occurs,
the object will still be disposed, but "before executing 'catch'" wouldn't
apply in that case.
In the 2nd case ('try' inside 'using'), the connection object will be
disposed too even I decide to exit from the function in catch?

Yes. Again, whether an exception occurs or not, the object will be
disposed.

That's the whole point of the "using" statement. No matter how you
structure the code in which it's contained, the object(s) referenced in
the "using" statement are guaranteed to be disposed no matter what
happens. Changing the structure of the code may change accessibility of
variables for specific sections of the code, but the disposing behavior
(which is why you're using "using" in the first place) remains unchanged.

Pete
 
Back
Top