Question

during beta testing we discovered connection pooling error messages . Therefore I have been going through the code and closing down the SqlDataReader objects wherever they have been left unclosed. What I need to know is how to close a datareader (or if there is a need at all to close) that is specified in the SelectStatement attribute of the SqlDataSource or ObjectDataSource tags. Could there be connection leak if they are not handled?

Thanks in advance !

Was it helpful?

Solution

I tend to use the "using" keyword, especially when dealing with opening and closing connections to a database. "using" is a shortcut to the Dispose pattern - here is a link to the MSDN writeup, and here is a link to a useful blog entry with an overview.

OTHER TIPS

To improve performance of Close()/Dispose() consider calling Cancel() on the associated command object before disposing or closing the reader, especially when you didn't reach the end of the record set.

For example:

            using (var cmd = ... ))
            {
                using (var reader = (DbDataReader) cmd.ExecuteReader())
                {
                    try
                    {
                        ConsumeData(reader); // may throw
                    }
                    catch(Exception)
                    {
                        cmd.Cancel();
                        throw;
                    }
                }
            }

My understanding is that with SqlDataSource, connection management is performed for you, and you have nothing to fear.

ObjectDataSource doesn't talk to the database directly in the first place, so it will be safe -- as long as the underlying object performs its connection and reader management correctly.

As others have mentioned, Close() and using are your friends for the classes you use with ObjectDataSource.

My hunch is that if you've scrubbed the codebase effectively, you've probably eradicated the issue.

We had the same problems here in a production environment.

Solved the issue. The problem first was, there were no using statements at all in my code. (It was build a few years ago, with some less knowledge).

I then tried putting the SqlDataSource in a using clause. But this didn't help either.

The trick here is, just like tvanfosson and Mischa are suggesting, putting the reader in a using clause. This is the object that actually closes the connection.

The number of connections shrunk to the minimum pool size of 10 at medium load.

Calling .Dispose() should handle clean up and release any held resources, but the .Close() method should be getting called as well when an object is done reading from the reader.

I believe that the SqlDataSource will handle it's own connection/reader issues, so no worries there. As for your manual connections, I've found this pattern useful in the past:

   using (SqlConnection connection = new SqlConnection(connectionString))
   {
      try
      {
         SqlCommand command = connection.CreateCommand();
         command.CommandText = ...

         connection.Open();
         using (SqlDataReader reader = command.ExecuteReader())
         {
            do
            {
               while (reader.Read())
               {
                  ... handle each row ...
               }
            } while (reader.NextResult());
         }
      }
      catch (Exception ex)
      {
          ... error handling ...
      }
      finally
      {
         if (connection != null && connection.State == ConnectionState.Open)
         {
            connection.Close();
         }
      }
  }

I agree, that for the ObjectDataSource the closing should be handled by its Select method. My ObjectDataSource Select method returns a SqlDataReader. My concern is ... will the SqlDataReader be rendered useless when closed after returning it to the UI. e.g. see the following sample code. I have not tried it and don't want to do it at this stage of development.

SqlDataReader MySelectMethod(){
   SqlDataReader dr = null;
   try{
      dr = DBObject.GetDataReader();
      return dr;
   }
   finally{
      dr.Close();
   }
}

Thanks for all the inputs received so far !

...........

My understanding is that with SqlDataSource, connection management is performed for you, and you have nothing to fear.

ObjectDataSource doesn't talk to the database directly in the first place, so it will be safe -- as long as the underlying object performs its connection and reader management correctly.

As others have mentioned, Close() and using are your friends for the classes you use with ObjectDataSource

.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top