Question: I have the code below to query records from a stored procedure but am concerned I may not be disposing what I need to or am disposing when the object would be cleared by the Garbage Collector shortly afterward anyway.

Do I need to dispose the SqlDataReader since it is within the try catch block?  

Do I need to run both cmd.Dispose and cmd.Connection.Close or does one infer the other?

Would the garbage collector eventually dispose of all these objects anyway (maybe not timely enough) or do these objects implictly require dispose possibly because of using unmanaged code?

```
public void GetData(string studentID)
    {
        SqlCommand cmd = new SqlCommand("sp_stored_proc", 
                new SqlConnection(Settings.Default.connectionString)) 
                { CommandType = CommandType.StoredProcedure };
        try
        {
            cmd.Connection.Open();
            cmd.Parameters.AddWithValue("@student_id", studentID);
            SqlDataReader dr = cmd.ExecuteReader();

         //do something with the data

            if (dr != null)
                dr.Dispose();
        }
        catch
        {
            //error handling
        }
        finally
        {
            if (cmd != null)
            {
                cmd.Dispose();
                cmd.Connection.Close();
            }

        }

    }

```

Answer: 
If you use something like this:

```
public void GetData(string studentID)
{
    using (SqlConnection connection = new SqlConnection(Settings.Default.connectionString))
    {
        connection.Open();

        using (SqlCommand command = connection.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "sp_stored_proc";
            command.Parameters.AddWithValue("@student_id", studentID);

            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                // do something with the data
            }
        }
    }
}

```

then all of your Disposable objects will get disposed of correctly. Calling Dispose() on the SqlConnection, SqlCommand and SqlDataReader objects (which is what the using block does when it exits) closes them correctly.

Additionally, this approach keeps all of your variables scoped to where they are used.

The downside to this approach is that if you need error handling using a try/catch, you have to either wrap it around the whole method body, or use several of them to handle connection errors differently from reading errors, etc...
you should open Connection firstly by Connection.Open();
then use the methods such as SqlDataReader to read
after all,close SqlDataReader firstly and then close connection

you can use keyword "using" to dispose it, but it is not a good idea

in fact the keyword "using" is to dispose the object automatically.
in other word,the object should achieve dispose method