Jared
Jared

Reputation: 6060

using & try/catch nesting

This question is more of a what is the RIGHT way to do something...

The question...is there a proper nesting order between a using block and a try/catch?

Is it ok to nest the entire using statement inside of a try/catch and maintain the benefits of a using block? (or will an exception cause the closing portion of the using statement to get thrown out the window)

Or should you nest the try/catch inside the using statements and only surround the statements that do database access?

Is...

try {
     using( tsmtcowebEntities db = new tsmtcowebEntities() ) {
          violationList = ( from a in db.DriverTrafficViolationDetails
                            where a.DriverTrafficViolation.DriverApplicationId == DriverAppId
                            orderby a.DateOfOccurance descending
                            select a ).ToList<DriverTrafficViolationDetail>();
          GeneralViolation = ( from a in db.DriverTrafficViolations
                               where a.DriverApplicationId == DriverAppId
                               select a ).FirstOrDefault();
     }
} catch { }

less/more correct than...

using( tsmtcowebEntities db = new tsmtcowebEntities() ) {
     try {
          violationList = ( from a in db.DriverTrafficViolationDetails
                            where a.DriverTrafficViolation.DriverApplicationId == DriverAppId
                            orderby a.DateOfOccurance descending
                            select a ).ToList<DriverTrafficViolationDetail>();
          GeneralViolation = ( from a in db.DriverTrafficViolations
                               where a.DriverApplicationId == DriverAppId
                               select a ).FirstOrDefault();
     } catch { }
}

Upvotes: 10

Views: 2327

Answers (4)

user166390
user166390

Reputation:

using nests predictably with try/catch and Dispose will be called all on paths. Predictably means control always flows from inner -> outer scopes (for both Exceptions and normal flow return).

The question is then: when should the catch be executed in relationship to the Dispose and what should the scope of the catch be? The answer to this will vary by code but must obviously be "on the inside" if access to db is required and "on the outside" if code executed as part of the using* might be the source of the exception.

(Also, empty catch blocks are icky! I am assuming they are there "for demonstration purposes".)

Happy coding.


*Note that an outer-catch will catch exceptions thrown from new tsmtcowebEntities() or (as pointed out by J.N.) the Dispose, should any exist. (It is another topic entirely if it acceptable for either construct to throw an exception ;-) I prefer to catch exceptions as close to the source as possible and let exceptions I don't know how to deal with "bleed out" uncaught except in certain top-level constructs (e.g. event handlers).

Upvotes: 1

Andrew Kennan
Andrew Kennan

Reputation: 14157

It's really a matter of style and how narrow you want to keep the scope of db:

If the using is inside the try/catch block the db variable will only be accessible within the try portion.

If the using is outside the try/catch block it will be visible within the catch portion.

Regardless, the variable will be disposed of correctly because the using block is the equivalent of a try/finally.

Personally I would be wondering why you need to catch exceptions there at all and what, if anything, you are able to do with them.

Upvotes: 2

J.N.
J.N.

Reputation: 8421

The later is better: it will avoid masking exceptions eventually thrown dy dispose. See this article.

Upvotes: 5

Glenn Ferrie
Glenn Ferrie

Reputation: 10390

I would suggest placing the try/catch within the using because regardless of whether or not an exception is throw you should dispose of types the Disposable entity container

Upvotes: 0

Related Questions