Will putting a “using” statement around a DataReader close it?

后端 未结 4 1447
栀梦
栀梦 2020-12-18 17:52

I usually write my DataReader code like this:

try
{
    dr = cmd.ExecuteReader(CommandBehavior.SingleResult);
    while (dr.Read())
    {
               


        
相关标签:
4条回答
  • 2020-12-18 18:20

    Yes. using calls Dispose. Calling Dispose on SqlDataReader closes it.

    This is psuedo-code of SqlDataReader gleaned from Reflector:

        public void Dispose()
        {
            this.Close();
        }
    
        public override void Close()
        {
            if( !IsClosed )
                CloseInternal(true);
        }
    
        private void CloseInternal(bool closeReader)
        {
            try
            {
                // Do some stuff to close the reader itself
            }
            catch(Exception ex)
            {
                this.Connection.Abort();
                throw;
            }
    
            if( this.Connection != null && CommandBehavior.CloseConnection == true )
            {
                this.Connection.Close();
            }
        }
    
    0 讨论(0)
  • 2020-12-18 18:20

    Typically, using() calls Dispose() and that calls close() in turn.

    In case of a DataReader, the Close is called only when CommandBehavior.CloseConnection is set (see comments of this article http://weblogs.asp.net/joseguay/archive/2008/07/22/ensure-proper-closure-amp-disposal-of-a-datareader.aspx).

    EDIT: This article says something interesting:

    The Close() method on the SqlDataReader calls an InternalClose() method, which does not call Dispose. Note that previously we stated the correct way to do this was to have your close call dispose. To make it even more confusing the Dispose() method actually calls the Close() method so for this object the order is reversed.

    0 讨论(0)
  • 2020-12-18 18:39

    From what I can recall, if an exception occurs in a Using block, then the Dispose method is still called on the object. I usually have a Using statement for all disposable objects, without a Try..Catch.

    EDIT: Forgot to say that for some objects, calling Dispose will in turn call Close for that object.

    0 讨论(0)
  • 2020-12-18 18:43

    Unlike the example here, my practice has been to employ a using block for the connection, the command and the reader. Note that you can stack nested using blocks to lower the indentation cost.

    static void HasRows(SqlConnection connection)
    {
        using (connection)
        using (SqlCommand command = new SqlCommand(
        "SELECT CategoryID, CategoryName FROM Categories;",
        connection))
        {
            connection.Open();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
                            reader.GetString(1));
                    }
                }
                else
                {
                    Console.WriteLine("No rows found.");
                }
                reader.Close();
            }   
        }
    }
    
    0 讨论(0)
提交回复
热议问题