Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my application hang while trying to close a SqlConnection object?

I am trying to get column information in C# from a SQL table on SQL Server. I am following the example in this link: http://support.microsoft.com/kb/310107 My program strangely gets hung up when it tries to close the connection. If the connection is not closed, the program exits without any Exceptions. Here's my code:

SqlConnection connection = new SqlConnection(@"MyConnectionString"); 
connection.Open();
SqlCommand command = new SqlCommand("SELECT * FROM MyTable", connection);
SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo); // If this is changed to CommandBehavior.SchemaOnly, the program runs fast.
DataTable table = reader.GetSchemaTable();
Console.WriteLine(table.Rows.Count);
connection.Close(); // Alternatively If this line is commented out, the program runs fast.

Putting the SqlConnection inside a using block also causes the application to hang unless CommandBehavior.KeyInfo is changed to CommandBehavior.SchemaOnly.

using (SqlConnection connection = new SqlConnection(@"MyConnectionString"))
{
    connection.Open();
    SqlCommand command = new SqlCommand("SELECT * FROM MyTable", connection);
    SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo); // If this is changed to CommandBehavior.SchemaOnly, the program runs fast even here in the using
    DataTable table = reader.GetSchemaTable();
    Console.WriteLine(table.Rows.Count);
}

The table in question has over 3 million rows, but since I am only obtaining the Schema information, I would think this wouldn't be an issue. My question is: Why does my application get stuck while trying to close a connection?

SOLUTION: Maybe this isn't optimal, but it does work; I inserted a command.Cancel(); statement right before Close is called on connection:

SqlConnection connection = new SqlConnection(@"MyConnectionString"); 
connection.Open();
SqlCommand command = new SqlCommand("SELECT * FROM MyTable", connection);
SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo); // If this is changed to CommandBehavior.SchemaOnly, the program runs fast.
DataTable table = reader.GetSchemaTable();
Console.WriteLine(table.Rows.Count);
command.Cancel(); // <-- This is it.
connection.Close(); // Alternatively If this line is commented out, the program runs fast.
like image 364
Jesus is Lord Avatar asked Apr 18 '12 21:04

Jesus is Lord


1 Answers

I saw something like this, long ago. For me, it was because I did something like:

SqlCommand command = new SqlCommand("SELECT * FROM MyTable", connection);
SqlDataReader reader = command.ExecuteReader();

// here, I started looping, reading one record at a time
// and after reading, say, 100 records, I'd break out of the loop

connection.Close();  // this would hang

The problem is that the command appears to want to complete. That is, go through the entire result set. And my result set had millions of records. It would finish ... eventually.

I solved the problem by adding a call to command.Cancel() before calling connection.Close().

See http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=610 for more information.

like image 151
Jim Mischel Avatar answered Oct 17 '22 05:10

Jim Mischel