.net SqlConnection, не закрываемый, даже когда в рамках использования {}

Вам даже не нужен пользовательский оператор для этого, потому что вы можете использовать timeout() и retry():

return database[index].pipe(
  timeoutWith(5 * 60 * 1000),
  retry(),
);

retry() будет повторно подписываться на его источник, если он выдаст ошибку. Тем не менее, все это ожидает, что database[index] обновляется всегда, когда вы подписываетесь на него.

16
задан Ash 6 November 2008 в 14:57
поделиться

6 ответов

От MSDN (DataContext Constructor (IDbConnection)):

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

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

    protected override void Dispose(bool disposing)
    {
        if(disposing && this.Connection != null && this.Connection.State == ConnectionState.Open)
        {
            this.Connection.Close();
            this.Connection.Dispose();
        }
        base.Dispose(disposing);
    }

Лично, я счастливо дал бы его (регулярный контекст данных, w/o взлом выше) открытое соединение, пока я "использовал" соединение (разрешающий мне выполнить несколько операций) - т.е.

using(var conn = GetConnection())
{
   // snip: some stuff involving conn

   using(var ctx = new FooContext(conn))
   {
       // snip: some stuff involving ctx
   }

   // snip: some more stuff involving conn
}
19
ответ дан 30 November 2019 в 17:40
поделиться

Эти SqlProvider используемый LINQ DataContext только закрывает соединение SQL (до SqlConnectionManager.DisposeConnection), если это было то для открытия его. При предоставлении уже открытого SqlConnection объект к DataContext конструктор он не закроет его для Вас. Таким образом необходимо записать:

using (SqlConnection conn = GetConnection())
using (DataContext db = new DataContext(conn))
{
    ... Code 
}
7
ответ дан 30 November 2019 в 17:40
поделиться

Я испытал ту же проблему с помощью Платформы Объекта. Мой ObjectContext был перенесен вокруг a using блок.

Соединение было установлено, когда я звонил SaveChanges(), но после using оператор был вне объема, я заметил, что Studio управления SQL все еще имел a "AWAITING COMMAND" для SQL-клиента.NET. Похоже, что это имеет отношение к поведению поставщика ADO.NET, которому включили организацию пула подключений по умолчанию.

От "Используя Организацию пула подключений с SQL Server" на MSDN (шахта акцента):

Организация пула подключений уменьшает количество раз, что должны быть открыты новые соединения. Пулер поддерживает владение физического соединения. Это управляет подключениями путем поддержания ряда активных соединений для каждого данного конфигурирования соединений. Каждый раз, когда вызовы пользователя Open на соединении Пулер надеется видеть, существует ли доступное соединение в пуле. Если объединенное соединение доступно, оно возвращает его вызывающей стороне вместо того, чтобы открыть новое соединение. Когда приложение звонит Close на соединении Пулер возвращает его объединенному набору активных соединений вместо того, чтобы на самом деле закрыть его. После того как соединение возвращается к пулу, это готово быть снова использованным на следующем Open звонить.

Также ClearAllPools и ClearPool кажется полезным для явного закрытия всех объединенных соединений в случае необходимости.

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

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

Решение:

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

В Вашем полученном DataContext - добавляют Расположение () функция. В этом - располагают внутреннее соединение.

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

Хорошо спасибо за парней справки, это было решено теперь..

По существу я взял элементы большинства ответов выше и реализовал конструктора DataContext как выше (я уже перегрузил конструкторов, таким образом, это не было большое изменение).

// Variable for storing the connection passed to the constructor
private System.Data.SqlClient.SqlConnection _Connection;

public DataContext(System.Data.SqlClient.SqlConnection Connection) : base(Connection)
{
    // Only set the reference if the connection is Valid and Open during construction
    if (Connection != null)
    {
        if (Connection.State == System.Data.ConnectionState.Open)
        {
            _Connection = Connection;                    
        }
    }           
}

protected override void Dispose(bool disposing)
{        
    // Only try closing the connection if it was opened during construction    
    if (_Connection!= null)
    {
        _Connection.Close();
        _Connection.Dispose();
    }

    base.Dispose(disposing);
}

причина того, чтобы сделать это, а не некоторые предложения выше - то, что доступ this.Connection в расположить методе бросает ObjectDisposedException.

И вышеупомянутые работы, а также я надеялся!

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

Эти Dispose должен закрыть соединения, как , MSDN указывает:

, Если SqlConnection выходит из объема, он не будет закрыт. Поэтому необходимо явно закрыть соединение путем вызова Близко или Расположить. Закройте и Расположите, функционально эквивалентны. Если Объединение значения организации пула подключений имеет значение true или да, базовое соединение возвращается назад к пулу соединения. С другой стороны, если Объединение имеет значение false или нет, базовое соединение с сервером закрывается.

Мое предположение было бы то, что Ваша проблема имеет некоторое отношение GetContext().

0
ответ дан 30 November 2019 в 17:40
поделиться
Другие вопросы по тегам:

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