Вопрос по IDisposable - PullRequest
       3

Вопрос по IDisposable

4 голосов
/ 28 октября 2010

У меня вопрос, зачем мне IDisposable? У меня есть класс, который потребляет некоторые ресурсы это должно быть освобождено. У меня есть два варианта

Без IDisposable

class SomeUtilityClass
{
 public Stop()
 {
   // free resources
 }
}

С IDisposable

    class SomeUtilityClass, IDisposable
    {
     public void Dispose()
     {
       // free resources
     }
    }

Так зачем мне здесь IDisposable? Не имеет значения, как назвать функцию.

class Program
{

 public Main(..)
 {
   SomeUtilityClass _class = new SomeUtilityClass();

   // clean up when we've done

  _class.Stop();

   // OR
  _class.Dispose();

 }
}

Ответы [ 7 ]

5 голосов
/ 28 октября 2010

Поскольку IDisposable поддерживается C #, и вы можете использовать классный using синтаксис:

using (IDisposable someDisposable = new ...)
{
    // your code with someDisposable 
}

Это на самом деле преобразуется компилятором во что-то вроде:

IDisposable someDisposable = new ...
IDisposable someDisposable2 = someDisposable ;
try
{
    // your code with someDisposable 
}
finally
{
    if (someDisposable2 != null)
    {
        someDisposable2.Dispose();
    }
}

Таким образом, если в блоке using произойдет какое-либо исключение, ваш объект все равно будет удален.

3 голосов
/ 28 октября 2010

Вы действительно должны использовать IDisposable только тогда, когда ваш класс потребляет неуправляемые ресурсы, и они должны быть немедленно освобождены (потоки, дБ и т. Д.).

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

Вызов IDisposable помечает объект как доступный для сборки мусора немедленно, но если он не реализован правильно, вы можете заставить свой объект повышать генерацию сборки мусора, которая можетвызвать нехватку памяти (обратитесь к Jeffery Richters CLR через c # 3, если вы хотите получить полное объяснение).

быстрый гугл обнаружил это: http://kleahy -technical.blogspot.com / 2009/01 /idisposable-and-garbage-collection.html

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

EDIT: есть много информации и о стеке потока: Использование сборки мусора?

2 голосов
/ 28 октября 2010

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

Обычное использование IDisposable - это когда вы открываете интерфейс, который обрабатывает подключения к данным, и вы хотитевсе производные классы, чтобы избавиться, когда они сделаны.

Рассмотрим это:

public interface IDataCtx
{
   void CallDB();
}

public class MyDataCtx : IDataCtx
{ 
   private SqlConnection dc;

   public MyDataCtx() { dc = new SqlConnection(); dc.Open(); }

   public void CallDB();
   {
       dc.Something();
   }
}

Позволяет вам сделать что-то вроде этого:

IDataCtx ctx = new MyDataCtx();
ctx.CallDB();

Но подождите, чтооб этом открытом соединении?Э-э-э!

Если вы сделали IDataCtx : IDisposable (и внедрили код в свой производный ctx), вы можете сделать это:

IDataCtx ctx;
using (ctx = new MyDataCtx())
{
   ctx.CallDB();
}

Гарантируя, что независимо от используемой вами реализации IDataCtx, онавсегда будет утилизироваться (даже в случае исключения).

Вот так я все равно его использую.(плюс это просто хорошая практика).

1 голос
/ 28 октября 2010

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

Легко читаемую небольшую статью о том, когда реализовывать IDisposable и финализаторы, можно найти здесь: http://nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html

1 голос
/ 28 октября 2010

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

1 голос
/ 28 октября 2010

Это соглашение используется на языке C #.

Вы также получите в свое распоряжение изящное заявление using.

using (SomeUtilityClass _class = new SomeUtilityClass()) {

} // Dispose is automatically called
1 голос
/ 28 октября 2010

IDisposable взаимодействует с ключевым словом using, чтобы упростить его очистку после себя, например:

using (var file = new FileStream(...))
{
    file.Write(...);
}

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

...