Неуправляемые ресурсы, IDisposable и пользовательские типы

Еще одна тема на эту тему, так как я устал читать бесчисленные темы, чтобы найти ответ на мои вопросы:)

Допустим, у нас есть следующий класс:

public class MyClass
{
   private const string conString = "connection string";

   private int Operation()
   {
      int count = 0;

      using(var con = SqlConnection(conString))
      {
         string select_cmd = "SELECT * FROM TABLE";

         using(var cmd = new SqlCommand(select_cmd, con))
         {
            using(var reader = cmd.ExecuteReader())
            {
               while(reader != null && reader.Read())
                  count++;
            }
         }
      }

      return count;
   }

}

Поскольку соединение с базой данных создается внутри оператора using, поэтому будут вызваны методы con.close() и в конечном итоге con.dispose(), существует ли необходимость в реализации IDisposable для MyClass? Будет ли MyClass собирать мусор, когда он выходит из области видимости?

РЕДАКТИРОВАТЬ:

Спасибо за ваши ответы, это то, что я думал, но мне нужно было прояснить это. Еще один вопрос.

Если в моем классе есть несколько Operations(), которые выполняют некоторую работу с базой данных, лучше с точки зрения потребления ресурсов иметь член SqlConnection, создавать и открывать его в конструкторе классов и реализовывать IDisposable, чтобы закрыть его вместо использовать операторы "using" в каждой операции (открывать и закрывать базу данных для каждой операции)? Конечно, таким образом, я должен только создавать экземпляр и использовать объект MyClass при использовании операторов.

3 ответа

Решение

Нет, вам нужно реализовать IDisposable только в том случае, если ваш класс удерживается на экземпляре SqlConnection вне метода Operation(), так что он поддерживается живым с самим классом (например, если вы связывали его с полем члена класса или имущество).

Экземпляр SqlConnection будет помечен как подлежащий очистке до того, как ваш класс выйдет из области видимости, поскольку этот экземпляр вышел из области действия в блоке using. Наиболее важным является то, что неуправляемое соединение с базой данных (инкапсулированное SqlConnection) было освобождено с помощью вызова Dispose. Управляемая часть SqlConnection будет освобождена, когда GC почувствует достаточное давление, чтобы оправдать выполнение GC.

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

РЕДАКТИРОВАТЬ

Что касается вашего второго вопроса, то лучше использовать и располагать экземпляры SqlConnection для каждого метода, потому что этот конкретный клиентский класс базы данных внутренне реализует пул соединений (т. Е. Он действительно не закрывает соединение при его удалении на некоторое время, так что при новом SqlConnection создается, он использует один из пула открытых соединений).

См. (Старый, но действительный): http://msdn.microsoft.com/en-us/library/8xx3tyca%28v=vs.71%29.aspx

Если вы используете клиентский API базы данных, который не реализует свой пул, возможно, лучше управлять этим вручную, как вы предлагаете. Однако вы должны быть осторожны с синхронизацией доступа к соединению (то есть: не позволяйте двум потокам использовать его одновременно) и самостоятельно управлять проблемами жизни (например: если ваш класс остается живым все время работы приложения, вы ' Я буду держать ресурс базы данных открытым неограниченное время... и т. д.)

Большинство современных (MySql Connector.NET, SQL Server) реализуют пулы.

После Operation() После завершения все неуправляемые ресурсы, используемые в этом методе, удаляются. Для этого нет никаких оснований IDisposable, MyClass не держит открытыми неуправляемые ресурсы, поэтому ему не нужно реализовывать этот интерфейс.

Что касается вашего второго вопроса, экземпляры вашего класса будут собирать мусор, как и любой другой управляемый объект.

Нет, нет необходимости внедрять в интерфейс IDisposable, у вас нет ресурсов для освобождения.

Другие вопросы по тегам