При использовании COM-взаимодействия с Office (обычно Excel) я всегда тщательно проверяю, что я вызываю Marshal.ReleaseComObject
при каждой ссылке, чтобы избежать проблемы, когда Excel не завершает работу , как описано в этой статье базы знаний .
Как обеспечить завершение работы Excel при использовании Interop из приложения OOB Silverlight (с AutomationFactory.CreateObject
)?
В Silverlight нет метода Marshal.ReleaseComObject
и даже вызова GC.Collect
и GC.WaitForPendingFinalizers
не помогает.
Конечно, Microsoft не добавила эту функцию в Silverlight без механизма выпуска ссылок на COM?Мне кажется, что это показательный шаг для автоматизации внешних COM-серверов, таких как Excel.
Удивительное упущение, тем более что Пит Браун в разделе 5.5 своей книги «Silverlight 4 в действии»доходит до того, что о AutomationFactory.CreateObject
следует сказать, что:
Основной целью этой функции является обеспечение автоматизации других приложений, включая Microsoft Office.
ОБНОВЛЕНИЕ в ответ на комментарии Ганса.
Я не уверен, что проблема "тихого убийцы" существует в типичной автоматизации приложений Office.Обычное использование может выглядеть примерно так, как я часто видел в приложениях WinForms, не сталкиваясь с «отравленным RCW», описанным в статье, на которую ссылается Ганс:
- Создание Excel.Экземпляр приложения
- Открытие или создание рабочей книги
- Запись данных в рабочую книгу
- Показать Excel, если все прошло успешно, закрыть книгу и вызвать Application.Quit, если нет.
- Вызовите Marshal.ReleaseComObject, чтобы освободить все ссылки на объекты Excel.
Если не вызвать Marshal.ReleaseComObject, как рекомендовано Хансом, будет запущено несколько копий Excel.exe, как описано в статье базы знаний.упомянутое выше - крайне нежелательно.
ОБНОВЛЕНИЕ 2
Образец, который я использую для воспроизведения этого примера, является примером из исходного кода книги Пита Брауна «Silverlight 4 в действии».На этой странице есть ссылка для скачивания.Пример решения AutomatingExcel находится в Ch05.zip / 5.03.Чтобы воспроизвести:
- Убедитесь, что экземпляры Excel не запущены
- Запустите образец AutomatingExcel
- Открыта книга Excel
- Закрыть Excel
- Обратите внимание, с помощью диспетчера задач, что Excel все еще работает.
Установка всех динамических переменных на ноль и вызов GC.Collect (), кажется, работает, как указано в ответе AnthonyWJones.
ОБНОВЛЕНИЕ 2
Ответ Отаку - это то, что я искал - упаковывая ссылки в операторе using, ссылки COM освобождаются без необходимости вызывать GC.Collect.Немного экспериментов показывает, что более терпимо отказываться от каждой отдельной ссылки, в отличие от стандартного решения Marshal.ReleaseComObject
, описанного в статье базы знаний, на которую мы ссылаемся выше.
Было бы интересно иметь авторитетное представление о том, что именнодолжен быть утилизирован, чтобы обеспечить освобождение всех ссылок Excel.