Использование BackgroundWorker оставит процесс Excel запущенным после закрытия Excel
Я работаю над надстройкой Excel в C#, которая отображает индикатор выполнения во время симуляции. Я хочу, чтобы BackgroundWorker запускал симуляцию асинхронно и сообщал о ходе выполнения в форме индикатора выполнения.
Для метода моделирования требуется ссылка на текущее приложение Excel COM. У меня есть класс под названием ThisAddin
который реализует ExcelDna.Integration.IExcelAddIn
интерфейс и имеет статическое свойство, которое возвращает приложение.
Однако, как только фоновый работник попытается каким-либо образом использовать приложение, оно оставит процесс Excel запущенным даже после того, как я выйду из Excel.
Например, если я просто установлю свойство в приложении Excel следующим образом:
void backgroundworker_DoWork(object sender, DoWorkEventArgs e)
{
ThisAddIn.App.DisplayStatusBar = true;
}
Затем после запуска надстройки и закрытия Excel в моем диспетчере задач все равно будет запущен процесс Excel.
Есть ли способ гарантировать, что процесс будет убит? Создаю ли я другой экземпляр приложения в фоновом режиме? Я не понимаю, потому что если я вызову quit() для приложения из фонового рабочего, оно закроет все приложение, и процесс все равно останется запущенным!
Когда фоновый работник завершит работу, я обязательно вызову dispose() и прерву его текущий поток. Я использовал класс "AbortableBackgroundWorker", как предложено здесь. Но это все еще не решает мою проблему.
1 ответ
Проблема в том, что вы держите объекты Excel дольше, чем вы думаете. Два варианта, которые я видел, использовались успешно:
- Используйте Marshal.ReleaseComObject для каждого объекта Excel, к которому вы прикасаетесь.
- Создайте новый AppDomain и выполните всю свою работу в Excel. Затем выгрузите весь AppDomain, который гарантирует, что любые оставшиеся объекты будут удалены.
Вариант 1 легче понять, но он более хрупок и подвержен ошибкам.