как закрыть соединение / datareader при использовании SqlDataSource или ObjectDataSource - PullRequest
6 голосов
/ 20 октября 2008

во время бета-тестирования мы обнаружили сообщения об ошибках пула соединений. Поэтому я просматривал код и закрывал объекты SqlDataReader, где бы они не были закрыты. Что мне нужно знать, так это как закрыть устройство чтения данных (или, если есть необходимость вообще его закрыть), указанное в атрибуте SelectStatement тегов SqlDataSource или ObjectDataSource. Может ли быть утечка соединения, если они не обрабатываются?

Заранее спасибо!

Ответы [ 7 ]

12 голосов
/ 20 октября 2008

Я склонен использовать ключевое слово «using», особенно когда речь идет об открытии и закрытии соединений с базой данных. «using» - это ярлык для шаблона Dispose - здесь - ссылка на рецензию MSDN, а здесь - ссылка на полезную запись в блоге с обзором.

4 голосов
/ 17 октября 2009

Для повышения производительности Close () / Dispose () рассмотрите возможность вызова Cancel () для связанного командного объекта перед удалением или закрытием считывателя, особенно если вы не достигли конца набора записей.

Например:

            using (var cmd = ... ))
            {
                using (var reader = (DbDataReader) cmd.ExecuteReader())
                {
                    try
                    {
                        ConsumeData(reader); // may throw
                    }
                    catch(Exception)
                    {
                        cmd.Cancel();
                        throw;
                    }
                }
            }
2 голосов
/ 18 января 2011

У нас были такие же проблемы здесь, в производственной среде.

Решил проблему. Сначала проблема заключалась в том, что в моем коде вообще не было операторов использования. (Он был построен несколько лет назад с меньшими знаниями).

Затем я попытался поместить SqlDataSource в предложение using. Но это тоже не помогло.

Хитрость здесь в том, что, как предлагают tvanfosson и Mischa, поместить читателя в предложение использования. Это объект, который фактически закрывает соединение.

Количество соединений сократилось до минимального размера пула 10 при средней нагрузке.

2 голосов
/ 20 октября 2008

Насколько я понимаю, с SqlDataSource управление подключениями выполняется для вас, и вам нечего бояться.

ObjectDataSource не общается с базой данных напрямую, поэтому он будет в безопасности - до тех пор, пока базовый объект правильно выполняет свои подключения и управление считывателем.

Как уже упоминали другие, Close() и using ваши друзья по классам, которые вы используете с ObjectDataSource.

Я догадываюсь, что если вы эффективно очистили кодовую базу, вы, вероятно, устранили проблему.

0 голосов
/ 21 октября 2008

Я согласен, что для ObjectDataSource закрытие должно обрабатываться его методом Select. Мой метод ObjectDataSource Select возвращает SqlDataReader. Меня беспокоит ... станет ли SqlDataReader бесполезным при закрытии после возврата в пользовательский интерфейс. например см. следующий пример кода. Я не пробовал и не хочу делать это на данном этапе разработки.

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

Спасибо за все полученные данные!

...........

Я понимаю, что с SqlDataSource, управление соединением выполняется для вас, и у вас есть нечего бояться.

ObjectDataSource не общается с база данных непосредственно в первую очередь, так что это будет безопасно - до тех пор, пока базовый объект выполняет свои управление подключением и считывателем правильно.

Как уже упоминали другие, Close () и используя ваши друзья для занятий вы используете с ObjectDataSource

.

0 голосов
/ 21 октября 2008

Я считаю, что SqlDataSource решит свои проблемы с подключением / считывателем, поэтому не стоит беспокоиться. Что касается ваших ручных подключений, я нашел этот шаблон полезным в прошлом:

   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();
         }
      }
  }
0 голосов
/ 20 октября 2008

Вызов .Dispose () должен обрабатывать очистку и освобождать любые удерживаемые ресурсы, но метод .Close () также должен вызываться, когда объект завершает чтение из читателя

...