Как я могу уничтожить COM-объекты в C#?

Что является методами для уничтожения объектов Excel COM Interop в C# помимо них:

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

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

9
задан perilbrain 22 March 2010 в 19:34
поделиться

6 ответов

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

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

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

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

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

0
ответ дан 4 December 2019 в 06:56
поделиться

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

0
ответ дан 4 December 2019 в 06:56
поделиться

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

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

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

0
ответ дан 4 December 2019 в 06:56
поделиться

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

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

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

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

15
ответ дан 4 December 2019 в 06:56
поделиться

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

Имейте в виду:

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...
2
ответ дан 4 December 2019 в 06:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: