#c_sharp #excel #office_interop
В программе на C# работаю с книгой Excel следующим образом. using Excel = Microsoft.Office.Interop.Excel; Excel.Application excel; excel = new Excel.Application(); excel.Workbooks.Open( "1.xlsx"); Excel.Worksheet sheet = (Excel.Worksheet)excel.ActiveSheet; //Читаю некоторые ячейки excel.ActiveWorkbook.Save(); excel.ActiveWorkbook.Close(); excel.Quit(); GC.Collect(); После выполнения этого кода процесс EXCEL.EXE продолжает висеть в диспетчере задач, но завершается после закрытия моей программы. Если убрать последние 3 строчки, то процесс висит в диспетчере и не завершается после закрытия моей программы. Как же правильно закрыть Excel?
Ответы
Ответ 1
Необходимо освобождать все используемые COM-объекты с помощью Marshal.ReleaseComObject. Кроме того, есть такое правило: Никогда не используйте две точки с объектами COM. Когда вы пишете: excel.Workbooks.Open( "1.xlsx"); тут на самом деле создаются два COM-объекта. Оба нужно освободить после окончания работы с ними. Поэтому нужно разбить это выражения на два, с сохранением каждого COM-объекта в переменной. Кроме того, желательно предусмотреть гарантированное освобождение даже в случае исключений. Финальный код может выглядеть примерно так: Workbooks workbooks = null; Workbook workbook = null; try { workbooks = excel.Workbooks; workbook = workbooks.Open( "1.xlsx"); } finally { Marshal.ReleaseComObject(workbook); Marshal.ReleaseComObject(workbooks); } Так нужно поступить со всеми используемыми COM-объектами. Ваш код работы с Excel должен располагаться в блоке try, код закрытия и освобождения всех используемых ресурсов - в блоке finally.Ответ 2
if (application != null) { application.WorkbookBeforeClose -= new Excel.AppEvents_WorkbookBeforeCloseEventHandler(application_WorkbookBeforeClose); application.Quit(); Marshal.ReleaseComObject(application); GC.Collect(); GC.WaitForPendingFinalizers(); process.WaitForExit(100); }
Комментариев нет:
Отправить комментарий