Освобождение COM-объектов из .NET
От: Lonely Dog Россия  
Дата: 02.08.10 14:32
Оценка:
Привет!

В .NET я новичек, т.ч. не пинайте если что

В программе на С# создаю экземпляр объекта, оборачивающего COM-объект (ATL out-of-proc server). Обертка реализует IDisposable, в ней делаю так:

void IDisposable.Dispose()
{
  _MyObj = null;


В итоге, если из программы выйти сразу же, COM-сервер (он в отд. процессе) остается жить в памяти. Если же перед выходом поставить паузу (5 сек), то сервер успешно завершается. Такое ощущение, что за эти 5 секунд происходит сборка мусора. Так и должно быть или все-таки нет? Как вообще правильно из .NET освобождать COM-ресурсы?

Заранее спасибо
Re: Освобождение COM-объектов из .NET
От: Warturtle  
Дата: 02.08.10 15:41
Оценка: 4 (1)
Здравствуйте, Lonely Dog, Вы писали:

LD>Привет!


LD>В .NET я новичек, т.ч. не пинайте если что


LD>В программе на С# создаю экземпляр объекта, оборачивающего COM-объект (ATL out-of-proc server). Обертка реализует IDisposable, в ней делаю так:


LD>
LD>void IDisposable.Dispose()
LD>{
LD>  _MyObj = null;
LD>


LD>В итоге, если из программы выйти сразу же, COM-сервер (он в отд. процессе) остается жить в памяти. Если же перед выходом поставить паузу (5 сек), то сервер успешно завершается. Такое ощущение, что за эти 5 секунд происходит сборка мусора. Так и должно быть или все-таки нет? Как вообще правильно из .NET освобождать COM-ресурсы?


LD>Заранее спасибо

Marshal.ReleaseComObject?
Re[2]: Освобождение COM-объектов из .NET
От: Lonely Dog Россия  
Дата: 02.08.10 15:43
Оценка:
Здравствуйте, Warturtle, Вы писали:

LD>>Заранее спасибо

W>Marshal.ReleaseComObject?
ОК, а если у меня экземпляры этих оберток передаются из класса в класс?
Т.е. есть класс1, один из его методов создает класс2, передавая ему COM-объект.
Если они оба вызовут ReleaseComObject, будет ошибка. Как быть в этом случае?
Re: Освобождение COM-объектов из .NET
От: MozgC США http://nightcoder.livejournal.com
Дата: 02.08.10 15:49
Оценка: 4 (1)
Почитайте вот эту тему:

http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c/1893653#1893653
Re[2]: Освобождение COM-объектов из .NET
От: Lonely Dog Россия  
Дата: 02.08.10 16:01
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Почитайте вот эту тему:


MC>http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects-in-c/1893653#1893653

Спасибо, почитал.
Т.е. по идее надо вызывать ReleaseComObject.
А как же быть в ситуации, когда одним RCW владеют несколько объектов. Ведь вызывать ReleaseComObject должен только один?
Ввести свой счетчик ссылок?
Re: Освобождение COM-объектов из .NET
От: _FRED_ Черногория
Дата: 02.08.10 16:33
Оценка:
Привет, Дима!

LD>В .NET я новичек, т.ч. не пинайте если что

LD>В программе на С# создаю экземпляр объекта, оборачивающего COM-объект (ATL out-of-proc server). Обертка реализует IDisposable, в ней делаю так:
LD>  _MyObj = null;


Это практически бесмысленная в шарпе конструкция.

LD>В итоге, если из программы выйти сразу же, COM-сервер (он в отд. процессе) остается жить в памяти.


"выйти сразу же" — завершить процесс? Каким образом — обычным (нормально выйдя из Main) или явным через Kill\FailFast?

LD>Если же перед выходом поставить паузу (5 сек), то сервер успешно завершается. Такое ощущение, что за эти 5 секунд происходит сборка мусора. Так и должно быть или все-таки нет?


Так и должно быть.

LD>Как вообще правильно из .NET освобождать COM-ресурсы?


Если не требуется детерминированное освобождение всех ссылок и подойдёт вариант, когда ссылки декрементятся при сборке мусора, то можно вообще не управлять ничем. Оно само справится. Если требуется гарантированное освобождение ресурса к определённому моменту, то лучше всю работу с КОМовским объектом вынести в отдельный домен. В нём поработать (опрять же не заморачиваясь с ReleaseComObject), а потом домен выгрузить.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Освобождение COM-объектов из .NET
От: MozgC США http://nightcoder.livejournal.com
Дата: 02.08.10 16:34
Оценка:
Здравствуйте, Lonely Dog, Вы писали:

LD>Спасибо, почитал.

LD>Т.е. по идее надо вызывать ReleaseComObject.
LD>А как же быть в ситуации, когда одним RCW владеют несколько объектов. Ведь вызывать ReleaseComObject должен только один?
LD>Ввести свой счетчик ссылок?

Я если повторно вызываю ReleaseComObject() (работаю с Excel) то у меня просто возвращается -1, но никаких ошибок не происходит.
А вообще, вы должны решить, кто (какой класс или метод) отвечает за освобождение этого COM-объекта, тогда этот вопрос автоматом уйдет.
Re[2]: Освобождение COM-объектов из .NET
От: MozgC США http://nightcoder.livejournal.com
Дата: 02.08.10 16:37
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Если требуется гарантированное освобождение ресурса к определённому моменту, то лучше всю работу с КОМовским объектом вынести в отдельный домен. В нём поработать (опрять же не заморачиваясь с ReleaseComObject), а потом домен выгрузить.


C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.
Re[3]: Освобождение COM-объектов из .NET
От: _FRED_ Черногория
Дата: 02.08.10 16:43
Оценка:
Здравствуйте, MozgC, Вы писали:

_FR>>Если требуется гарантированное освобождение ресурса к определённому моменту, то лучше всю работу с КОМовским объектом вынести в отдельный домен. В нём поработать (опрять же не заморачиваясь с ReleaseComObject), а потом домен выгрузить.


MC>C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.


Значит где-то что-то куда-то утекает. У меня как рах Эксель работа сначала в отдельном домене железобетонно, но уж очень часто нужен был, поэтому перенесли в основной и при самом активном использовании при выходе из приложения все (даже три экселины поднимаются) созданные мной Excel.exe завершаются самостоятельно без каких-бы то нибыло дополнительных приседаний с маршаллером.

Что требуется — явно закрывать корректно все буки.
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Освобождение COM-объектов из .NET
От: vmpire Россия  
Дата: 02.08.10 17:07
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

MC>>C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.


_FR>Значит где-то что-то куда-то утекает. У меня как рах Эксель работа сначала в отдельном домене железобетонно, но уж очень часто нужен был, поэтому перенесли в основной и при самом активном использовании при выходе из приложения все (даже три экселины поднимаются) созданные мной Excel.exe завершаются самостоятельно без каких-бы то нибыло дополнительных приседаний с маршаллером.

_FR>Что требуется — явно закрывать корректно все буки.
Тут может быть ещё нюанс, кроме висящих ссылок: Out of process сервера не обязаны выгружаться при уходе последней ссылки. Они вообще довольно самостоятельные в этом плане — сами регистрируют объекты, сами решают, когда выгрузится... Так что, Excel, как и любой другой Out of process сервер имеет полное право не выгружаться сразу, а подождать немного, вдруг его ещё позовут.
Конкретно у Excel я больших задержек не замечал, но у другого сервера могут быть другие правила.
Re[5]: Освобождение COM-объектов из .NET
От: alexey.kostylev Новая Зеландия http://alexeykostylev.livejournal.com/
Дата: 03.08.10 05:16
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Здравствуйте, _FRED_, Вы писали:


MC>>>C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.


_FR>>Значит где-то что-то куда-то утекает. У меня как рах Эксель работа сначала в отдельном домене железобетонно, но уж очень часто нужен был, поэтому перенесли в основной и при самом активном использовании при выходе из приложения все (даже три экселины поднимаются) созданные мной Excel.exe завершаются самостоятельно без каких-бы то нибыло дополнительных приседаний с маршаллером.

_FR>>Что требуется — явно закрывать корректно все буки.
V>Тут может быть ещё нюанс, кроме висящих ссылок: Out of process сервера не обязаны выгружаться при уходе последней ссылки. Они вообще довольно самостоятельные в этом плане — сами регистрируют объекты, сами решают, когда выгрузится... Так что, Excel, как и любой другой Out of process сервер имеет полное право не выгружаться сразу, а подождать немного, вдруг его ещё позовут.
V>Конкретно у Excel я больших задержек не замечал, но у другого сервера могут быть другие правила.

когда я активно пользовал Excel в дельфи, на ExcelApplication надо было давать Quit чтобы он выгружался. В шарпе тоже самое наверно
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.