1

I'm having some trouble. I have a SqlCommand in a using block. Usually this works fine. This time however, the code exits the using block but the command does not get disposed. It has me stumped.

using (SqlCommand transferCommand = new SqlCommand(strHeaderStoredProcedure, connection))
{
    transferCommand.CommandType = System.Data.CommandType.StoredProcedure;
    transferCommand.Parameters.Add("@InvtTransferID", SqlDbType.UniqueIdentifier).Value = InvtTransferID;
    SqlDataReader transferReader = transferCommand.ExecuteReader();
    while (transferReader.Read())
    {
        //do my stuff, this all works fine
    }
}


using (SqlCommand transferCommand = new SqlCommand(strDetailsStoredProcedure, connection))
{
    transferCommand.CommandType = System.Data.CommandType.StoredProcedure;
    transferCommand.Parameters.Add("@InvtTransferID",     SqlDbType.UniqueIdentifier).Value = InvtTransferID;
    SqlDataReader transferReader = transferCommand.ExecuteReader(); <-- Error happens here.
}

I'm trying to reuse my connection to run a bunch of stored procedures. It is the strangest thing. I have some code on another form that is virtually identical and it runs fine, disposing the command and allowing me to make another. Any ideas what I'm doing wrong? (I'm trying to make this code look nice in the post but it seems to be beyond my meager power...so sorry for the messy code.)

Error is: There is already an open DataReader associated with this Command which must be closed first.

2
  • Can you provide the actual exception or error message that you're getting? Commented May 29, 2014 at 23:02
  • The error text is: There is already an open DataReader associated with this Command which must be closed first. However, the datareader is usually closed when the command is disposed. Commented May 29, 2014 at 23:08

2 Answers 2

6

What you have is an open SqlDataReader (transferReader), Close and Dispose the datareader or use a using() for it.

I assume the command is not being released because the reader is still open.

Sign up to request clarification or add additional context in comments.

3 Comments

Well, you're right. Putting the SqlDataReader in a using statement fixed my problem right up. That is odd though, I thought a using would ALWAYS dispose of the object in the using statement as well as any objects created within its scope regardless of any other conditions. I guess this is a wrong assumption?
Using() cannot guarantee the object destruction, as you stated guarantees the Dispose call, but you don't know what that Dispose does internally, per example supose you have a class with a thread and in your Dispose call you do Thread.Abort, the object is disposed but the thread is still alive until the thread is finished internally or the ThreadAbortException is raised which can happen some time after the Abort call.
TIL using statement is not a magic bullet. Thanks for taking the time to explain it to me.
1

As a bit of extra info, here is what the compiler does behind the scenes when you write an using statement.

using(IDisposable x)
{
  //some work here
}

Turns into

IDisposable x = //some IDisposable

try
{
    //do work  here
}
finally
{
  x.Dispose()
}

As Gusman mentioned , using cannot guarantee the object destruction, it just calls the object's dispose method. It's the IDisposable's reponsability to clean up any used resources

I hope this helps

1 Comment

Yeah, that makes perfect sense now. It is odd though. I've probably used this construct scores of times now and this is the first time I've had a problem. So I wasn't suspecting the SqlDataReader since it had always worked fine before. I guess it just goes to show just because something works doesn't mean it is right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.