NoWar
NoWar

Reputation: 37633

Why we have to close objects under the finally {} block?

Can someone explain why #1 approach is better than #2?

1

try
{

}
catch
{
}
finally
{
reader.Close();  
dataStream.Close();
response.Close();
}

2

try
{

reader.Close();  
dataStream.Close();
response.Close();

}
catch
{
}

Upvotes: 0

Views: 664

Answers (4)

emgee
emgee

Reputation: 520

If an exception occurs anywhere in your try block before all the objects are closed, they won't be closed. The finally block allows you to perform clean-up should an exception be raised in your try block.

As others have mentioned, the using approach is the way I go with my own code. The compiler translates the using into try{} finally{} blocks for you. Check out the following MSDN link: http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Cheers.

Upvotes: 0

4444
4444

Reputation: 3680

Since a Try block is designed to handle possible failures, it's important to handle both a successful and unsuccessful case. Items inside the Try block might get called, they might not - depending on if and where a failure takes place.

By placing closure statements into the finally block, you ensure the statements will always be called, whether or not the Try section was successful. This way, you won't leave reader, datastream, and response left open - even if a failure did take place.

Upvotes: 0

spender
spender

Reputation: 120380

I prefer approach 3

using(var reader = ...)
using(var dataStream = ...)
using(var response = ...)
{
    //...
}//all disposed (and implicitly closed) at the end of this scope

Using this construct, the compiler converts to approximately this:

var reader = ...;
var dataStream = ...;
var response = ...;
try
{
    //...
    //even if an error happens here
}
finally
{
   //this code still runs before control leaves this method.
   reader.Close();  
   dataStream.Close();
   response.Close();
}

Upvotes: 4

Reed Copsey
Reed Copsey

Reputation: 564323

If reader.Close() raises an exception, both of your options will never close dataStream or response.

However, in your #2 option, if code prior to reader.Close() raises an exception, no objects will be closed. In #1, you at least guarantee that you'll call reader.Close() always, even if something else raises an exception.

In general, though, any object with a Close() method should also implement Close via IDisposable.Dispose(), in which case I would always prefer to use using instead of either of these options:

using(var reader = CreateReader())
{
  using(var dataStream = CreateDataStream(reader))
  {
    using(var response = CreateResponse(dataStream))
    {
       // Use objects
    }
  }
}

This will enforce that all objects are properly closed, but is cleaner.

Upvotes: 7

Related Questions