Заставить OleDbConnection освободить дескриптор файла - PullRequest
3 голосов
/ 19 мая 2010

Смежный вопрос

Мой код не освобождает дескриптор файла даже после того, как я вызываю dispose для инициализированной OleDbException. Есть ли способ явно заставить программу освободить дескриптор файла?

Ответы [ 2 ]

5 голосов
/ 12 апреля 2012

По умолчанию для соединений с базой данных .NET используется пул . Вызов Close() и Dispose() просто освобождает соединение обратно в пул, но фактически не заставляет его закрываться. В конце концов, он выйдет из пула и фактически закроется.

После небольшого исследования, кажется, есть два основных способа предсказуемо приблизить его:

  1. Отключить пул в строке подключения - попробуйте добавить OLE DB Services = -2;, который должен предоставить вам все услуги, кроме пула
  2. Попробуйте использовать OleDBConnection.ReleaseObjectPool()

Для последнего подхода вам может понадобиться поиграть с таймаутами - выдержка из связанной статьи MSDN:

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

Перед окончательным удалением пула должно произойти следующее:

  1. Вызовите Close, чтобы вернуть объект подключения в пул.
  2. Разрешить каждому объекту соединения время вне пула.
  3. Вызов ReleaseObjectPool.
  4. Запустить сборку мусора.

У меня есть вариант использования для этого на работе, когда некоторые собственные программы должны взаимодействовать с частью старого, негибкого, нестабильного и абсолютно критического проприетарного программного обеспечения. Необходимо как можно быстрее открыть общий файл базы данных MDB, чтобы свести к минимуму окно, в котором другое программное обеспечение может «возникнуть» (очень плохо).

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

0 голосов
/ 19 мая 2010

Не уверен, почему ваш код не закрывает дескриптор после вызова Dispose (), поскольку это вызывает Close () за кулисами, но следующее может помочь вам написать код в привычном для вас виде:

using (OleDbConnection conn = new OleDbConnection(connString))
{
    //your stuff here
    conn.Close();  //not necessary, but doesn't hurt
}

Это закроет ваш дескриптор независимо от того, было ли сгенерировано исключение или нет. Использование блоков приведет к закрытию / удалению ресурсов в конце блока.

...