Почему вызов SqlClient. SqlDataReader Близко () метод так или иначе?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
18
задан Community 23 May 2017 в 11:51
поделиться

8 ответов

Несомненно, это будет собрано, когда это выйдет из объема (если их не другие ссылки на него). Когда это будет собрано, это будет закрыто через Располагать () метод. Однако Вы никогда действительно знаете, когда GC собирается освободить вещи; если Вы не закрываете свои средства чтения, у Вас очень быстро заканчиваются доступные соединения с базой данных.

Дополнительные материалы для чтения

~ William Riley-Land

36
ответ дан 30 November 2019 в 05:46
поделиться

@Lieutenant Frost

, Как правило, в нашем магазине, мы явно переносим все вызовы базы данных в Попытку... Наконец блок, с наконец разделяют ловлю и закрытие соединений данных. Это стоит крошечного бита усилия сохранить себя сильная головная боль поиска и устранения неисправностей.

у меня есть подобное правило, но я требую, чтобы объекты, реализовывая IDisposable использовали блок 'использования'.

using (SqlConnection conn = new SqlConnection(conStr))
{
     using (SqlCommand command = new SqlCommand())
     {
        // ETC
     } 
}

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

17
ответ дан 30 November 2019 в 05:46
поделиться

Одна хорошая практика (как долго, поскольку Вы не снова используете соединения) должна добавить Поведение Команды к SqlDataReader для закрытия соединения, когда это расположено:

SqlDataReader rdr = cmd.ExecuteReader( CommandBehavior.CloseConnection );

Добавление это гарантирует, что соединение с базой данных закрывается, когда объект SqlDataReader закрывается (или собрал "мусор").

, Поскольку я заявил прежде, тем не менее, Вы не хотите делать это, если Вы - планирование многократного использования соединения с базой данных для другой операции в рамках того же метода.

10
ответ дан 30 November 2019 в 05:46
поделиться

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

Из объема не означает непосредственную сборку "мусора".

Ваше приложение должно 'играть по правилам' в ряде уровней. Закрытие соединений помогает Вам сделать это. Давайте исследуем несколько из тех уровней.

1: Вы не полагаетесь на сборку "мусора". Идеально сборка "мусора" не должна должна быть существовать. Но это делает. Но наиболее конечно Вы не должны полагаться на него.

2: Вы не держите свои соединения с базой данных. В то время как соединения обычно объединяются, поскольку Вы нашли, что существует предел. Содержание этого дольше, чем необходимый делает Ваше приложение плохим яблоком.

3: Вы не генерируете сетевой трафик. Каждое соединение с базой данных является по существу соединением TCP. Хранение его открытый, вероятно, генерирует сетевой трафик вроде, Вы все еще там? да. Маленький трафик да, но в переполненной сети это - плохая практика. И сам SQL Server использует ресурсы для поддержания соединения. Ресурсы другие люди, пытающиеся добираться до того SQL-сервера, могли лучше использовать.

При размышлении о доступе к базе данных также необходимо думать о сетевых ресурсах. Некоторые способы получить данные плохи, потому что они могут взять с собой ненужный материал для поездки. Более ранние версии ADO были довольно известны за этот тип материала. Возвращение информации о схеме, когда Вы просто хотите данные. Несомненно, только с несколькими соединениями это не проблема. Но с тех пор, когда делает любую базу данных, имеют только несколько соединений. Поэтому думайте об этом материале и попытайтесь не злоупотребить ресурсами.

, Когда Ваше веб-приложение только имеет 100 пользователей, Вы не можете заботиться. Но что относительно 100 000? Всегда рассматривайте то, что происходит, когда Вы масштабируетесь.

4
ответ дан 30 November 2019 в 05:46
поделиться

Если Вы явно не закрываете его, то это находится, там ожидая сборщика "мусора" для "собирания" его... Только после этого происходит, делает это становится выпущенным назад к пулу Соединения ADO.Net, который будет снова использован другим Соединением. Открытый запрос, таким образом, в течение всего прошедшего времени, любые другие запросы на соединение должны будут создать совершенно новое, даже при том, что существует совершенно хороший, находящийся там неиспользованный, который мог использоваться...

В зависимости от того, какой длины это перед выполнениями GC, и сколько Запросов к базе данных выполняется, у Вас могли закончиться доступные соединения с базой данных.

, Но на Команде существует дополнительный параметр. ExecuteReader () метод, названный CommandBehavior. Это - перечисление со значениями: CommandBehavior. Значение по умолчанию, CommandBehavior. SingleResult, CommandBehavior. SchemaOnly, CommandBehavior. KeyInfo, CommandBehavior. SingleRow, CommandBehavior. SequentialAccess и CommandBehavior. CloseConnection

, который Это перечисление сделало, чтобы FlagsAttribute приписал, который позволяет поразрядную комбинацию его членских значений. Это - последнее значение, (CommandBehavior. CloseConnection), который релевантен здесь. Это говорит Объекту команды закрывать соединение, когда средство чтения данных закрывается. http://msdn.microsoft.com/en-us/library/system.data.commandbehavior.aspx

, К сожалению, значение по умолчанию не должно закрывать соединение, когда средство чтения данных закрывается, но Вы можете, (и если) передают этот параметр как CommandBehavior. CloseConnection, когда Вы хотите, чтобы Ваш метод выпустил соединение назад с пулом сразу, когда Вы сделаны с ним...

3
ответ дан 30 November 2019 в 05:46
поделиться

'Управляемый' ресурс, упомянутый термином 'управляемый код', является памятью.Именно. Любой другой дефицитный ресурс должен быть перенесен с доступным шаблоном, включая соединения с базой данных.

причина это - проблема для Вас, то, что сборщик "мусора" не выполняет для каждого объекта момент, это выходит из объема. Намного более эффективно собрать больше объектов менее часто. Таким образом, если Вы будете ожидать коллектора для расположения объектов (и да, если Вы реализуете idisposable, то он в конечном счете будет), Вы, возможно, содержать много соединений с базой данных открываетесь намного дольше, чем Вы понимаете.

2
ответ дан 30 November 2019 в 05:46
поделиться

Это не Соединение, это - проблема, но Курсор SQL, сохраненный SqlDataReader. При попытке открыть секунду, не закрывая первое, то она выдаст исключение.

1
ответ дан 30 November 2019 в 05:46
поделиться

Также учтите то, что происходит, когда исключение выдается - Вы никогда не знаете, будет ли соединение закрыто, если Вы внезапно вынуждены покинуть выполняющийся код.

, Как правило, в нашем магазине, мы явно переносим все вызовы базы данных в Попытку... Наконец блок, с наконец разделяют ловлю и закрытие соединений данных. Это стоит крошечного бита усилия сохранить себя сильная головная боль поиска и устранения неисправностей.

1
ответ дан 30 November 2019 в 05:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: