Dispose(), Try-Catch and Using
The using statement, not to be confused with the more accustomed using directive, is a useful shorthand for working with classes that need to explicitly release unmanaged resources.
Bad
Consider opening a connection to a SQL Server database using a SqlConnection. Here’s a typical (bad) example:
string cnnStr = "Data Source=(local);Initial Catalog=Northwind2;Integrated Security=SSPI;";
SqlConnection cnn = new SqlConnection(cnnStr);
cnn.Open();
// ...work with database
cnn.Dispose();
If the database isn’t available then the call to Open will throw a SqlException. This means that Dispose will never be called, so the underlying database connection will not be closed or returned to the connection pool.
Better
A more resilient solution would be to wrap this code in a try-finally block, to make sure that the Dispose method is always called:
string cnnStr = "Data Source=(local);Initial Catalog=Northwind2;Integrated Security=SSPI;";
SqlConnection cnn = new SqlConnection(cnnStr);
try
{
cnn.Open();
// ...work with database
}
finally
{
cnn.Dispose();
}
Best
A more succinct, but functionally equivalent, solution is to use the using statement:
string cnnStr = "Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;";
using (SqlConnection cnn = new SqlConnection(cnnStr))
{
cnn.Open();
// ... work with database
}
The object provided to the using statement must implement the IDisposable interface, which guarantees that the object imlpements a Dispose method. The object is always disposed as soon as control leaves the using block scope, even if it’s because an exception was thrown. This way, as with the try-finally example above, you can always guarantee that the underlying database connection will be released.
Not just for databases
Any class that uses unmanaged resources, such as file handles, network sockets or registry handles, can be placed in a using statement. Here are a few example from the .NET class library: