Как правильно обрабатывать переменные класса с помощью методов Dispose / Finalize - PullRequest
0 голосов
/ 29 сентября 2018

Я в недоумении по поводу того, как обращаться с классом, содержащим переменные с помощью методов Dispose / Finalize.Я хочу, чтобы этот класс содержал свои собственные методы Dispose / Finalize, которые вызывают Dispose для каждой переменной;однако и документация C #, и все остальные ответы / примеры по StackOverflow вызывают некоторую путаницу.

Основная путаница возникает из-за отсутствия ясности между тем, что является «управляемым» или «неуправляемым» объектом.Например, документация здесь , в которой объясняется, как реализовать Dispose, просто использует комментарии-заполнители, которые просто заявляют: «Освободите все неуправляемые объекты здесь».или «Освободите здесь любые другие управляемые объекты».

Подпадает ли переменная класса с Dispose / Finalize под категорию управляемых или неуправляемых?(Кроме того, следует ли мне беспокоиться о переменных класса, которые НЕ содержат каких-либо реализаций Dispose / Finalize? Учитывая, что существует два типа «управления», означает ли это, что те, у кого нет «Dispose», все равно должны быть каким-то образом удалены?)

То есть, как правильно обращаться с этим классом?

class BaseClass : IDisposable {

   MyDisposeableObject disposeMe; // object with Dispose/Finalize
   Dictionary<string,int> anotherObject; // just some arbitrary other object

   bool disposed = false;

   public BaseClass() {
      disposeMe = new MyDisposeableObject();
      anotherObject = new Dictionary<string,int>();
   }

   public void Dispose() { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   protected virtual void Dispose(bool disposing) {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         // Should I use "disposeMe.Dispose()" here?
      }

      // Free any unmanaged objects here.
      // OR should I use "disposeMe.Dispose()" here?

      // Also should I be doing anything with "anotherObject"?

      disposed = true;
   }

   ~BaseClass() {
      Dispose(false);
   }
}

1 Ответ

0 голосов
/ 29 сентября 2018

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

Вы должны вызывать disposeMe.Dispose (), только если «disinging = true».Потому что это управляемый класс / ресурс.Я предполагаю, что он также правильно реализует этот шаблон удаления и уничтожения.

Почему бы вам не попробовать использовать какой-либо управляемый объект за пределами блока if (утилизации)?

Потому что GC не может и не собирает ваши объекты, следуя графику от владельца к владельцу.Таким образом, когда метод Dispose вызывается Destructor, объект disposeMe уже может быть собран и недоступен.Таким образом, вы не можете / не должны распоряжаться им в этой области.

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

...