Проблема с зависанием взаимодействия COM-объектов - PullRequest
7 голосов
/ 21 декабря 2010

У меня есть приложение, которое использует COM-взаимодействие для создания электронной таблицы, которая открывается в Excel на компьютере клиента.Однако кажется, что процесс EXCEL.exe не всегда завершается, когда пользователь закрывает Excel, если я смотрю на диспетчер задач.

Если бы я сохранял книгу и программно закрывал Excel, я быиспользуйте Marshal.ReleaseComObject() для очистки, но так как я зависел от ручного закрытия программы, я не уверен, что делать.Есть предложения?

Ответы [ 4 ]

9 голосов
/ 21 декабря 2010

Excel не может завершить работу, пока все его внепроцессные объекты не будут освобождены.Так что он просто скрывает свой пользовательский интерфейс и продолжает работать.Пока ваша программа не закроется или вы не обнулите все ссылки на объекты Excel и поток финализатора не запустится.Выход из вашей программы будет очевидным решением.Или вы можете принудительно запустить поток финализатора:

GC.Collect();
GC.WaitForPendingFinalizers();

ReleaseComObject () редко работает, потому что так легко забыть промежуточную ссылку на COM-объект.Как и WorkBooks [index], это перечислитель, которого вы не видите.Позволить GC принять это решение для себя было бы более разумным выбором, если вы продолжите работать и выполнять работу, то это произойдет.

3 голосов
/ 21 декабря 2010

Возможно, Excel.exe все еще открыт, потому что пользователь открыл другой документ в том же экземпляре приложения Excell.В этом случае вам, вероятно, не следует завершать процесс Excel.exe.

Если вы уверены, что закрыли все открытые документы и освободили все созданные объекты, то почему для вас важноубедиться, что Excel.exe завершает работу?Может, процесс обслуживает другое приложение или пользователя?

2 голосов
/ 20 декабря 2012

Если я открою приложение Excel и книгу с:

Excel.Application app = new Excel.Application();
Excel.Workbook wb = app.Workbooks.Open(...);

Затем я использую методы wb.Close(), app.Quit() в операторе finally (или другом подходящем событии закрытия). Это очищает процесс Exel.exe. Нет необходимости вызывать методы Marshall.ReleaseComObject или GC.

2 голосов
/ 21 декабря 2010

Может быть много причин (включая Ран), но одна из них, которую я часто вижу в MapPoint (другое приложение Microsoft с интерфейсом COM), заключается в том, что вы должны убедиться, что ВСЕ ссылки на объекты очищены, чтобы сборщик мусора мог их очистить.,Достаточно одного зависшего объекта, чтобы приложение не закрывалось и не выходило из списка процессов.

...