В программе на С# создаю экземпляр объекта, оборачивающего COM-объект (ATL out-of-proc server). Обертка реализует IDisposable, в ней делаю так:
void IDisposable.Dispose()
{
_MyObj = null;
В итоге, если из программы выйти сразу же, COM-сервер (он в отд. процессе) остается жить в памяти. Если же перед выходом поставить паузу (5 сек), то сервер успешно завершается. Такое ощущение, что за эти 5 секунд происходит сборка мусора. Так и должно быть или все-таки нет? Как вообще правильно из .NET освобождать COM-ресурсы?
Здравствуйте, Lonely Dog, Вы писали:
LD>Привет!
LD>В .NET я новичек, т.ч. не пинайте если что
LD>В программе на С# создаю экземпляр объекта, оборачивающего COM-объект (ATL out-of-proc server). Обертка реализует IDisposable, в ней делаю так:
LD>
LD>В итоге, если из программы выйти сразу же, COM-сервер (он в отд. процессе) остается жить в памяти. Если же перед выходом поставить паузу (5 сек), то сервер успешно завершается. Такое ощущение, что за эти 5 секунд происходит сборка мусора. Так и должно быть или все-таки нет? Как вообще правильно из .NET освобождать COM-ресурсы?
LD>Заранее спасибо
Marshal.ReleaseComObject?
Здравствуйте, Warturtle, Вы писали:
LD>>Заранее спасибо W>Marshal.ReleaseComObject?
ОК, а если у меня экземпляры этих оберток передаются из класса в класс?
Т.е. есть класс1, один из его методов создает класс2, передавая ему COM-объект.
Если они оба вызовут ReleaseComObject, будет ошибка. Как быть в этом случае?
Привет, Дима!
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.
Здравствуйте, Lonely Dog, Вы писали:
LD>Спасибо, почитал. LD>Т.е. по идее надо вызывать ReleaseComObject. LD>А как же быть в ситуации, когда одним RCW владеют несколько объектов. Ведь вызывать ReleaseComObject должен только один? LD>Ввести свой счетчик ссылок?
Я если повторно вызываю ReleaseComObject() (работаю с Excel) то у меня просто возвращается -1, но никаких ошибок не происходит.
А вообще, вы должны решить, кто (какой класс или метод) отвечает за освобождение этого COM-объекта, тогда этот вопрос автоматом уйдет.
Здравствуйте, _FRED_, Вы писали:
_FR>Если требуется гарантированное освобождение ресурса к определённому моменту, то лучше всю работу с КОМовским объектом вынести в отдельный домен. В нём поработать (опрять же не заморачиваясь с ReleaseComObject), а потом домен выгрузить.
C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.
Здравствуйте, MozgC, Вы писали:
_FR>>Если требуется гарантированное освобождение ресурса к определённому моменту, то лучше всю работу с КОМовским объектом вынести в отдельный домен. В нём поработать (опрять же не заморачиваясь с ReleaseComObject), а потом домен выгрузить.
MC>C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.
Значит где-то что-то куда-то утекает. У меня как рах Эксель работа сначала в отдельном домене железобетонно, но уж очень часто нужен был, поэтому перенесли в основной и при самом активном использовании при выходе из приложения все (даже три экселины поднимаются) созданные мной Excel.exe завершаются самостоятельно без каких-бы то нибыло дополнительных приседаний с маршаллером.
Что требуется — явно закрывать корректно все буки.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
MC>>C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.
_FR>Значит где-то что-то куда-то утекает. У меня как рах Эксель работа сначала в отдельном домене железобетонно, но уж очень часто нужен был, поэтому перенесли в основной и при самом активном использовании при выходе из приложения все (даже три экселины поднимаются) созданные мной Excel.exe завершаются самостоятельно без каких-бы то нибыло дополнительных приседаний с маршаллером. _FR>Что требуется — явно закрывать корректно все буки.
Тут может быть ещё нюанс, кроме висящих ссылок: Out of process сервера не обязаны выгружаться при уходе последней ссылки. Они вообще довольно самостоятельные в этом плане — сами регистрируют объекты, сами решают, когда выгрузится... Так что, Excel, как и любой другой Out of process сервер имеет полное право не выгружаться сразу, а подождать немного, вдруг его ещё позовут.
Конкретно у Excel я больших задержек не замечал, но у другого сервера могут быть другие правила.
Здравствуйте, vmpire, Вы писали:
V>Здравствуйте, _FRED_, Вы писали:
MC>>>C экселем например такое не прокатывало, пробовал работать с ним в отдельном AppDomain, но при выгрузке домена эксель так и оставался висеть в памяти.
_FR>>Значит где-то что-то куда-то утекает. У меня как рах Эксель работа сначала в отдельном домене железобетонно, но уж очень часто нужен был, поэтому перенесли в основной и при самом активном использовании при выходе из приложения все (даже три экселины поднимаются) созданные мной Excel.exe завершаются самостоятельно без каких-бы то нибыло дополнительных приседаний с маршаллером. _FR>>Что требуется — явно закрывать корректно все буки. V>Тут может быть ещё нюанс, кроме висящих ссылок: Out of process сервера не обязаны выгружаться при уходе последней ссылки. Они вообще довольно самостоятельные в этом плане — сами регистрируют объекты, сами решают, когда выгрузится... Так что, Excel, как и любой другой Out of process сервер имеет полное право не выгружаться сразу, а подождать немного, вдруг его ещё позовут. V>Конкретно у Excel я больших задержек не замечал, но у другого сервера могут быть другие правила.
когда я активно пользовал Excel в дельфи, на ExcelApplication надо было давать Quit чтобы он выгружался. В шарпе тоже самое наверно