Как я могу уничтожить COM-объекты в C #? - PullRequest
9 голосов
/ 15 марта 2010

Каковы методы уничтожения объектов Excel COM Interop в C #, кроме этих:

object_instance = null;
System.GC.collect();
&
System.Runtime.InteropServices.Marshal.ReleaseComObject(object);

Пожалуйста, предлагайте только встроенные методы, а не другие инструменты, такие как bigcannon и т. Д.

Ответы [ 6 ]

16 голосов
/ 15 марта 2010

Кикер в том, что если вы не удалили все ссылки на объект, даже GC.Collect не уничтожит его.

Правило в C # (или .NET в целом) заключается в том, что вы не можете уничтожить объект. Dispose () не будет делать это. Финализатор не сделает этого (правило № 2, не используйте финализатор, если вы не знаете, зачем он вам нужен, и никогда не вызывайте его напрямую).

Для .NET это то, что вам нужно сделать:

  1. Если объект содержит ссылки на неуправляемые объекты, реализуйте шаблон IDispose. И осуществить это полностью; это больше, чем просто предоставление метода Dispose ().
  2. Единственная причина иметь финализатор состоит в том, чтобы выпустить неуправляемые объекты, и только в том случае, если ваш объект не был правильно утилизирован. Как только ваш метод dispose вызывается, он должен выполнить очистку, а затем «убить» финализатор, вызвав GC.SuppressFinalize.
  3. Если вы используете объект, который реализует метод Dispose (), вызовите Dispose (), когда вы закончите с этим объектом. Лучшая практика заключается в выделении этого объекта с использованием блока. Выход из блока using вызовет Dispose () автоматически.
  4. Когда вы закончите с объектом, отбросьте все ссылки на объект, включая обработчики событий, делегаты и т. Д.
  5. Кроме того, доверьте сборщику мусора свою работу. Не связывайтесь с сборщиком мусора; вы, скорее всего, только усугубите ситуацию, если вы действительно, действительно, действительно не знаете, что делаете и почему.
15 голосов
/ 15 марта 2010

Сборщик мусора - единственный механизм, который может уничтожить управляемый объект , но вы обычно не вызываете его явно. Вы просто позволяете ему делать свое дело.

Точно так же, как вы никогда не выносите свой собственный мусор в депо, вы просто оставляете его на углу. Это всегда ответственность мусорщика.

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

Используя System.GC, вы можете попросить сборщика мусора сделать что-то раньше - запросить пользовательский запуск только для себя - но это, как правило, портит его расписание, и у него гораздо больше мусора, чем у вас, поэтому рекомендуемые.

2 голосов
/ 15 марта 2010

По большей части вы должны удалить все ссылки на объект. Только тогда сборщик мусора увидит и уничтожит его.

Помните об этом:

object_instance = null;

Все, что это делает, это уничтожает ссылку на object_instance. Это работает, если это единственная ссылка. Если есть другие ссылки, они не будут собраны.

var skywalker = new Person();
var object_instance = skywalker;

...

object_instance = null;
//It's still alive and won't be collected because skywalker lives...
0 голосов
/ 18 марта 2010

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

http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

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

0 голосов
/ 15 марта 2010

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

0 голосов
/ 15 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...