Why doesn't 'using' have a catch block? - c#

I understand the point of "using" is to guarantee that the Dispose method of the object will be called. But how should an exception within a "using" statement be handled? If there is an exception, I need to wrap my "using" statement in a try catch. For example:
Lets say there is an exception created in the creation of the object inside the using parameter
try
{
// Exception in using parameter
using (SqlConnection connection = new SqlConnection("LippertTheLeopard"))
{
connection.Open();
}
}
catch (Exception ex)
{
}
Or an Exception within the using scope
using (SqlConnection connection = new SqlConnection())
{
try
{
connection.Open();
}
catch (Exception ex)
{
}
}
It seems like if I already need to handle an exception with a try catch, that maybe I should just handle the disposing of the object as well. In this case the "using" statement doesn't seem to help me out at all. How do I properly handle an exception with "using" statement? Is there a better approach to this that I'm missing?
SqlConnection connection2 = null;
try
{
connection2 = new SqlConnection("z");
connection2.Open();
}
catch (Exception ex)
{
}
finally
{
IDisposable disp = connection2 as IDisposable;
if (disp != null)
{
disp.Dispose();
}
}
Could the "using" keyword syntax be a little more sugary...
It sure would be nice to have this:
using (SqlConnection connection = new SqlConnection())
{
connection.Open();
}
catch(Exception ex)
{
// What went wrong? Well at least connection is Disposed
}

Because you would be 'hiding' extra functionality inside an unrelated keyword.
However you could always write it this way
using (...) try
{
}
catch (...)
{
}
And this way the line represents your intentions -- a using statement that is also a try

using Has nothing to do with error handling. It's shorthand for "call Dispose when you leave this block." Your second code example is perfectly acceptable... why mess with what works?

The using block is just syntactic sugar for a try-finally block. If you need a catch clause, just use a try-catch-finally:
SqlConnection connection;
try
{
connection = new SqlConnection();
connection.Open();
}
catch(Exception ex)
{
// handle
}
finally
{
if (connection != null)
{
connection.Dispose();
}
}
Yes, this is more code than your theoretical "using-catch"; I judge the language developers didn't consider this a very high priority, and I can't say I've ever felt its loss.

I've had places where this would be useful. But more often, when I want to do this it turns out that the problem is in my design; I'm trying to handle the exception in the wrong place.
Instead, I need to allow it to go up to the next level — handle it in the function that called this code, rather than right there.

An interesting idea, but it would make the following kinda confusing:
using (SqlConnection connection = new SqlConnection())
using (SqlCommand cmd = new SqlCommand())
{
connection.Open();
}
catch(Exception ex)
{
// Is connection valid? Is cmd valid? how would you tell?
// if the ctor of either throw do I get here?
}

You are mixing concerns in my opinion. Resource management (i.e. disposale of objects) is completely separated from exception handling. The one-to-one mapping that you describe in your question is just a very special case. Usually exception handling will not happen in the same place as the using scope ends. Or you might have multiple try-catch regions inside a using block. Or ...

I recommend you use example #1 and #2 combined. The reason is your using statement could read a file, for instance, and throw an exception (i.e File Not Found). If you don't catch it, then you have an unhandled exception. Putting the try catch block inside the using block will only catch exceptions that occur after the using statement has executed. A combination of your example one and two is best IMHO.

The purpose of the "using" statement is to ensure that some type of cleanup operation will occur when execution exits a block of code, regardless of whether that exit is via fall-through, an exception, or return. When the block exits via any of those means, it will call Dispose on the parameter of using. The block exists, in some sense, for the benefit of whatever is being specified as the using parameter, and in general that thing won't care why the block was exited.
There are a couple of unusual cases for which provisions might be helpful; their level of additional utility would be well below that provided by having using in the first place (though arguably better than some other features the implementers see fit to provide):
(1) There is a very common pattern in constructors or factories of objects which encapsulate other IDisposable objects; if the constructor or factory exits via an exception, the encapsulated objects should be Disposed, but if it exits via return they should not. Presently, such behavior must be implemented via try/catch, or by combining try/finally with a flag, but it would IMHO be helpful if there were either a variation of using which would only call Dispose when it exited via exception, or else a keep using statement which would null out the temporary employed by the using statement to hold the object which needed disposal (since using cannot be preceded by an identifier, such a feature could be added in a manner somewhat analogous to yield return).
(2) In some cases, it would be helpful if the finally keyword extended to accept an Exception argument; it would hold the exception which caused the guarded clause to exit (if any), or null if the guarded clause exits normally (via return or fall-through), and if the using block could make use of interface IDisposeExOnly {void DisposeEx(Exception ex);} and Interface IDisposeEx : IDisposable, IDisposableExOnly {} (at compile-time, selected DisposeEx() if implemented, or Dispose() otherwise). This could allow transaction-based objects to safely support auto-commit (i.e. perform the commit if the passed-in exception is null, or roll-back if non-null) and would also allow for improved logging in situations where Dispose fails as a consequence of a problem within the guarded clause (the proper thing would be for Dispose to throw an exception which encapsulates both the exception that was pending when it was called, and the exception that occurred as a consequence, but there's presently no clean way to do that).
I don't know if Microsoft will ever add such features; the first, and the first part of the second, would be handled entirely at the language level. The latter part of the second would be at the Framework level.

Related

Is there any technical reason to write a catch block containing only a throw statement?

Disclaimer: It is well known that catch (ex) { throw ex; } is bad practice. This question is not about that.
While digging through Microsoft reference sources, I noticed the following pattern in a lot of methods:
try {
...
} catch {
throw;
}
No logging, no debugging code—just a plain simple catch { throw; }.
Since, obviously, the guys at Microsoft should be fairly proficient in the use of C#, what could be the point of doing that instead of just omitting the catch block (and the try statement) altogether? Is there a technical reason for coding like this, or is it purely a stylistic choice?
Note: I don't know if it is relevant, but all such instances I could find also contain a try-finally block nested inside the try clause of the try-catch block.
It affects when exception filters run.
Given
void f() {
using (var x = AcquireResource()) {
x.DoSomething();
x.DoSomethingElse();
}
}
versus
void f() {
try {
using (var x = AcquireResource()) {
x.DoSomething();
x.DoSomethingElse();
}
} catch {
throw;
}
}
with
void g() {
try {
f();
} catch (Exception ex) when (h()) {
// ...
}
}
The first version of f would allow the filter h() to be called before x got disposed. The second version of f ensures that x is disposed before external code is run.
In the code you link to, SqlConnectionHolder is used a lot, and catch { throw; } blocks are all around the use of SqlConnectionHolder.
As C# Specification describes:
When an exception occurs, the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing try statement, and the associated catch clauses of the try statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing try statement that encloses the point of the call to the current method. This search continues until a catch clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A catch clause that doesn't name an exception class can handle any exception.
Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.
in case of exception runtime first looks for catch clause that can handle it, which involve executing any associated exception filters. Undiscriminating catch block interrupt that search and make all nested finally blocks to be executed immediately.
That can be useful when you want to prevent caller from executing arbitrary code (in form of exception filter) before finally block. For example, when finally block affect security context of current thread.
Also, if exception will not be caught by any catch clause, then it will lead to thread termination. And in that case C# Specification did not provide any guaranty, that any finally block will be executed at all.
If the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined.
The code you linked is actually a very good example.
In my eyes, one should only use try catch blocks when dealing with things outside of their control, like file systems, external things basically.
In the code you linked the try catch is around the database stuff.
What this means is that by using this way of coding, they make sure there are no leaks, no connections remain open.
If anything goes wrong, such as wrong connection string, missing tables, whatever, the code is going to continue to execute, it will gracefully close the connection as shown in the finally block and it will finally throw meaning it will allow the client of that code to get the proper exception, get the entire stack as well and let them decide what to do when that happens.
To be honest I quite like what they did there.

C# SQL Connection try/catch vs using vs try/catch w/ using

I am the third generation to work on a system within my organization and of course there are differences in programming styles. I was wondering what the correct way of connecting to a database is as there are two different styles being used within the system. So whats the "correct" way?
Method 1:
try
{
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
using (SqlCommand command = new SqlCommand("StoredProcedure", con))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("foo", bar));
}
using (SqlDataReader reader = command.ExecuteReader())
{
//do stuff
}
}
}
catch (Exception ex)
{
//do stuff
}
Method 2:
// Variables
SqlCommand loComm;
SqlConnection loConn = null;
SqlDataReader loDR;
try
{
// Init command
loComm = new SqlCommand("foo");
loComm.CommandType = CommandType.StoredProcedure;
loComm.Parameters.AddWithValue("foo", bar);
// Init conn
loConn = new SqlConnection(String);
loConn.Open();
loComm.Connection = loConn;
// Run command
loDR = loComm.ExecuteReader();
//do stuff
}
catch (Exception ex)
{
//do stuff
}
While both methods work I am not sure which one is the most appropriate to use. Is there a reason to use one over the other? The second method is cleaner and easier to understand to me, but it doesn't automatically run the iDispose() function when it is finished.
Edit: My question is different then the one suggested, because one approach uses the "using" statement while the other doesn't. So my question is directly related to whether or not to utilize the "using" statements when making a database connection.
Thanks, for all the responses.
Method 2 is simply incorrect and should be repaired.
When completed, you will be left with IDisposable instances that have not been disposed. Most likely, this will play havoc with the connection management that goes on behind the scenes with SqlConnection, especially if this code gets thrashed a lot before GC decides to step in.
If an instance is IDisposable, then it needs to be Disposed of, preferably in the smallest scope possible. Using using will ensure that this happens, even if the code malfunctions and exceptions are thrown.
A using statement:
using(var disposableInstance = new SomeDisposableClass())
{
//use your disposable instance
}
is (give or take a few minor details) syntactic sugar for:
var disposableInstance = new SomeDisposableClass();
try
{
//use your disposable instance
}
finally
{
//this will definitely run, even if there are exceptions in the try block
disposableInstance.Dispose();
}
Even if something goes wrong in the try block, you can be assured that the finally block will execute, thereby ensuring that your disposables are disposed, no matter what happens.
In the first example, if there is an exception thrown, the objects wrapped in the using blocks will be properly closed and disposed.
In the second, you will manually need to dispose of your objects.
One other thing worth mentioning is that if you were planning on disposing of your objects only when an exception is thrown, you will have objects that are not disposed of, so you would need to implement a try..catch..finally and dispose the objects within the finally block.
The first is the better option.
The first one will close the connection if an exception is thrown.
The second one won't, so I'd say go with the first choice.
What the using block does is to warranty that the object Dispose method will always be invoked, no matter if an exception is thrown or not.
Dispose is a method used to clean up resources. In the case of a DB connection, the connection is released, which is really important.
So, the correct way in this case is using the using pattern.
The object included between the using parents mus be IDisposable whic means that it has a Dispose method that should be invoked when the object is no longer needed. If you don't invoke dispose, it will be disposde at any indeterminate time, when the garbage collector destroys the object. That's undesirable in case like a DB connection that must be closed as soon as possible.
The equivalen of usin is a try finally, which includes a call to Dispose within the finally block.
Reading here, it says:
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned. The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.
That sounds like the correct way is method 1.

using and try finally, what should I choose

I have the following code block;
using (var msResp = new MemoryStream(Resp))
{
try
{
Response resp = new Response(msResp);
SetClientIdentityResponseValue sirv = new SetClientIdentityResponseValue(resp, (int)Response.Properties.Value);
if (!sirv.IsCredentialsValid)
{
throw new Exception("Authentication failed.");
}
if (sirv.IsSubscriptionExpired)
{
throw new Exception("Subscription expired.");
}
}
finally
{
msResp.Close();
}
}
I have read somewhere that a using statement automatically disposes the object.
Question:
Is using the Try/Finally combination redundant, when I already use the using statement?
Yes, it is redundant.
The using statement ensures that Dispose is called even if an
exception occurs while you are calling methods on the object. You can
achieve the same result by putting the object inside a try block and
then calling Dispose in a finally block; in fact, this is how the
using statement is translated by the compiler.
using Statement (C# Reference)
You don't need the finally. In fact, the using block is implemented internally using a try... finally.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object.
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Its redundant. But remember, if you want to catch exception then you need a try-catch. using statement won't catch any exceptions. It just close and disposes the object.
Since you're calling Close rather than Dispose It's not blatantly obvious that the code is redundant.
The documentation for MemoryStream.Dispose indicates that the stream is closed when calling Dispose:
This method disposes the stream, by writing any changes to the backing store and closing the stream to release resources.
Which infers that Close is called. However, there's no harm in explicitly Closing the stream when you're done with it.
Bottom line: Is it redundant? Probably. Is it hurting anthing? Absolutely not. I'd prefer to be in the habit of cleaning up after myself, even if a janitor comes in behind me and has nothing to do (or cleans again).

Is IDisposeable Called if Un-Handled Exception is Encountered in a Using Statement?

If I have the following, will IDisposeable still be called on DisposeableObject, or will the object remain opened because an un-handled exception is encountered?
using ( DisposeableObject = new Object() )
{
throw new Exception("test");
}
A using is like wrapping your code in a try...finally and disposing in the finally, so yes, it should be called.
using expands to a try..finally block, so yes, it will call Dispose.
In the example you provided Dispose will be called before the exception is thrown.
The normal code for ensuring that dispose gets called looks like
var connection= new SqlConnection(connectionString);
try
{
// do something with the connection here
}
finally
{
connection.Dispose();
}
The usings statement replaces the need to write such a cumbersome statement.
using(var connection = new SqlConnection(connectionString))
{
// do something with the connection here
}
According to MSDN, yes. When control leaves the scope of the using statement, expect it to be disposed.
The object will be disposed as you will come out of scope when the exception bubbles up.
See: using Statement (C# Reference)
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

Multipule Operations in a finally block

Lets say you had some resource clean up like: This is C#.
try{/*stuff*/}
catch(Exception e) {/*rollback logs etc.*/}
finally{
if( context.Transaction != null )
context.Transaction.Dispose();
context.Connection.Close();
context.Connection.Dispose();
}
Would it be more robust to do this instead?
try{/*stuff*/}
catch(Exception e) {/*rollback logs etc.*/}
finally{
try{
if( context.Transaction != null )
context.Transaction.Dispose();
}catch(Exception e){/*logs*/}
finally{
context.Connection.Close();
context.Connection.Dispose();
}
}
This way if the transaction.dispose manages to fail at leat the connection will be given the chance to close.
Would it be more robust to do this instead?
You would be better with multiple using blocks.
First, your catch blocks will eat all exceptions and are not needed (can have try ... finally without any catches). Only use catch if you can handle (or add value to) the exception.
But better:
using (var resA = GetMeAResourceNeedingCleanUp())
using (var resB = new AnotherResourceNeedingCleanUpn(...)) {
// Code that might throw goes in here.
}
NB. Once an exception is winding back, and finally blocks are clearing up, throwing an other exception is likely to lead to (at best) confusion about which is being handled. This second guideline:
DO NOT throw exceptions from Dispose methods or finalizers. If you need to allow users to handle cleanup failures provide a separate Close method which can report its failure.
Note, the "Framework Design Guidelines" (2nd ed) has this as (§9.4.1):
AVOID throwing an exception from within Dispose(bool) except under critical
situations where the containing process has been corrupted (leaks, inconsistent
shared state, etc.).
Three points:
You don't need to call Close as well as dispose
Disposing of the transaction in a separate finally block is a better idea, as it guards against exceptions being thrown during disposal. (It shouldn't happen often, but it might do.)
The using statement is almost always the cleanest way to dispose of resources. I use this even if I also want a try/catch block, simply because it's the idiomatic way of saying, "This uses a resource which I want to be disposed at the end of the block"
Combining these would lead to two using statements:
using (SqlConnection conn = ...)
{
using (Transaction trans = ...)
{
}
}
If you want to avoid excessive indentation, you can write this as:
using (SqlConnection conn = ...)
using (Transaction trans = ...)
{
}
why would a Dispose call fail? You can also be too careful at some point. Like wrap every 'new' statement with a try/catch in case memory runs out...
I don't like my finally clauses to be too verbose (or any clause, for that matter). I would refactor your resource cleanup into some utility class. Keep all the nested try's and "if null" conditions there, so you get better reuse. For example, because your cleanup logic resides in only one location, you can easily change your mind later about whether you really need to call Dispose().
Even more important, your application code becomes much more comprehensible.
try{/*stuff*/}
catch(Exception e) {/*rollback logs etc.*/}
finally{
Utility.cleanup(context);
}

Categories