OberonCore https://forum.oberoncore.ru/ |
|
Подсистема Ctl. https://forum.oberoncore.ru/viewtopic.php?f=2&t=540 |
Страница 1 из 1 |
Автор: | Евгений Темиргалеев [ Пятница, 29 Июнь, 2007 15:54 ] |
Заголовок сообщения: | Подсистема Ctl. |
Вот такая проблема. Создаем новое приложение (сервер автоматизации). Выполняем обработку данных. После сборщик мусора должно все подобрать, а сервер по идее выгрузиться. Однако, он выгружаться и не думает. Попробуйте просто эти строки - потыкал по коммандеру - и получил кучу процессов Excel. Код: IMPORT CtlExcel := CtlExcel9; У кого есть какие идеи? Проблема в ББ реализации COM/Ctl?
PROCEDURE ... VAR excel: CtlExcel.Application; BEGIN excel := CtlExcel.NewApplication(); ... |
Автор: | Axcel [ Пятница, 29 Июнь, 2007 17:30 ] |
Заголовок сообщения: | Re: Подсистема Ctl. |
А Вы после обработки сделали excel.quit? |
Автор: | Евгений Темиргалеев [ Понедельник, 02 Июль, 2007 11:41 ] |
Заголовок сообщения: | |
Угу. Даже excel.Quit; excel := NIL; Kernel.Collect.... Если сделать окно ёкзеля видимым, то Quit видимость убирает, а процесс остается. Может в ББ что-то его держит. Вот только что? |
Автор: | Евгений Темиргалеев [ Понедельник, 02 Июль, 2007 11:46 ] |
Заголовок сообщения: | Против лома нет приема |
Пока выкручиваюсь прибиванием процесса: Код: PROCEDURE KillExcel;
VAR h, ph: WinApi.HANDLE; res: WinApi.BOOL; entry: WinTlhelp.PROCESSENTRY32W; BEGIN h := WinTlhelp.CreateToolhelp32Snapshot(WinTlhelp.TH32CS_SNAPPROCESS, 0); ASSERT(h # -1, 100); (* Получили снимок процессов *) entry.dwSize := SIZE(WinTlhelp.PROCESSENTRY32W); res := WinTlhelp.Process32FirstW(h, entry); IF res = WinApi.TRUE THEN ASSERT(entry.dwSize = SIZE(WinTlhelp.PROCESSENTRY32W), 101) (* Можем читать имя *) END; WHILE res = WinApi.TRUE DO (* StdLog.String(entry.szExeFile); StdLog.Ln; *) MtStrings.ToUpper(entry.szExeFile, entry.szExeFile); IF entry.szExeFile = "EXCEL.EXE" THEN ph := WinApi.OpenProcess(WinApi.PROCESS_TERMINATE, WinApi.FALSE, entry.th32ProcessID); ASSERT(ph # 0, 102); (* Процесс "открылся" *) res := WinApi.TerminateProcess(ph, 0); ASSERT(res # 0, 103); (* Процесс убился *) res := WinApi.CloseHandle(ph); ASSERT(res # 0, 104); (* Дескриптор удалился *) END; res := WinTlhelp.Process32NextW(h, entry) END; ASSERT(WinApi.GetLastError() = WinApi.ERROR_NO_MORE_FILES, 105); (* Чтение списка процессов завершилось успешно *) res := WinApi.CloseHandle(h); ASSERT(res # 0) (* Дескриптор удалился *) END KillExcel; Надо только юзерам сообщать, что во время работы екзелем пользоваться запрещается |
Автор: | Кривохатько С.А. [ Понедельник, 02 Июль, 2007 19:36 ] |
Заголовок сообщения: | |
Евгений Темиргалеев писал(а): Угу. Даже excel.Quit; excel := NIL; Kernel.Collect....
Если сделать окно ёкзеля видимым, то Quit видимость убирает, а процесс остается. Может в ББ что-то его держит. Вот только что? Проблема точно не в BB. Очень давно сталкивался с подобным и под .NET. Правда там эти процессы сами отмирали через некоторое (довольно большое) время. Решилось обертыванием работы с Excel в класс, экземпляр которого создавался локально в теле процедуры: Код: //код вне класса ExcelWork bool result = false; ExcelWork ew = new ExcelWork(this); result = ew.GenExcel(gr, ods, GenPaged); ew = null; GC.Collect(); return result; Кроме этого в этом классе был метод: Код: //метод класса ExcelWork private void NAR(Object o) { try{ System.Runtime.InteropServices.Marshal.ReleaseComObject(o); } finally{ o = null; } } С помощью которого "добивались" объекты Excel: Код: //метод класса ExcelWork
Excel.Application excelApp = null; Excel.Workbook wbk = null; try { excelApp = new Excel.Application(); excelApp.UserControl = false; excelApp.DisplayAlerts = false; wbk = excelApp.Workbooks.Add(Missing.Value); ............... wbk.Close(false,Missing.Value,Missing.Value); NAR(wbk); excelApp.Quit(); NAR(excelApp); GC.Collect(); GC.WaitForPendingFinalizers(); } catch(Exception e) { ............... Возможно обертывание в класс или NAR были лишними, точно уже не помню. Таже обратите внимание на UserControl и DisplayAlerts. |
Автор: | Кривохатько С.А. [ Понедельник, 02 Июль, 2007 23:24 ] |
Заголовок сообщения: | |
Мда, попробовал переложить выше-написанное в BB. Оказалось, что всё работает как должно, висящих в памяти процессов Excel не наблюдается. Исходный код: Код: MODULE ExamplesExcel;
IMPORT CtlExcel := CtlExcel9, Kernel; PROCEDURE OpenClose*; VAR excel: CtlExcel.Application; BEGIN excel := CtlExcel.NewApplication(); excel.PUTVisible(TRUE); excel.Quit; excel:=NIL; Kernel.Collect; END OpenClose; END ExamplesExcel. ^QExamplesExcel.OpenClose Версия BB - 1.6, Excel - 11(2003). Видимо это был глюк самого Excel 9-10, который исправили в 11ой версии. Как вариант - какой-нибудь некорректно написанный плагин может мешать закрываться Excel'у. |
Автор: | Евгений Темиргалеев [ Вторник, 03 Июль, 2007 09:14 ] |
Заголовок сообщения: | |
У меня BB 1.5, Excel 11. Этот пример работает также. Однако, когда между Quit и NewApplication стоит обработка - открытие книги и т.п, то процесс остается. Попробуйте (у меня excel остается): Код: PROCEDURE OpenClose*;
VAR excel: CtlExcel.Application; wb: CtlExcel.Workbook; BEGIN excel := CtlExcel.NewApplication(); excel.PUTVisible(TRUE); wb := excel.Workbooks().Open("E:\workbook.xls", NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL); excel.Quit; wb := NIL; excel:=NIL; Kernel.Collect; END OpenClose; |
Автор: | Кривохатько С.А. [ Среда, 04 Июль, 2007 01:22 ] |
Заголовок сообщения: | |
Евгений Темиргалеев писал(а): У меня BB 1.5, Excel 11. Этот пример работает также. Однако, когда между Quit и NewApplication стоит обработка - открытие книги и т.п, то процесс остается.
Подтверждаю. Как пишут здесь: http://support.microsoft.com/Default.aspx?kbid=317109 "This behavior is by design." Даже если заменить код на элементарный: Код: wbks: CtlExcel.Workbooks;
..................... wbks := excel.Workbooks(); wbks.Close(); wbks := NIL; ..................... получаем аналогичный результат. Остаётся либо изобретать Marshal.ReleaseComObject в BB, либо убивать процессы. |
Автор: | Вячеслав Бойко [ Суббота, 14 Июнь, 2008 12:16 ] |
Заголовок сообщения: | Re: Подсистема Ctl. |
В меню "COM" есть пункт "Collect", который вызывает процедуру HostMenus.Collect, которая и прибивает Excel. Код: VAR
app: CtlExcel.Application; ..... PROCEDURE Exit*; BEGIN app:= NIL; HostMenus.Collect; END Exit; |
Автор: | Вячеслав Бойко [ Среда, 18 Июнь, 2008 11:05 ] |
Заголовок сообщения: | Re: Подсистема Ctl. |
Куда утекает память? Код: MODULE TestExcel; IMPORT CtlT, Excel := CtlExcel9, StdLog, Services; TYPE Action = POINTER TO RECORD (Services.Action) END; VAR app: Excel.Application; ws: Excel.Worksheet; wb: Excel.Workbook; action: Action; range: Excel.Range; N: INTEGER; PROCEDURE (action: Action) Do; BEGIN N:= ws.Range(CtlT.Str("A1"), CtlT.Str("A1")).Value().Int(); Services.DoLater(action, Services.Ticks() + 1000) END Do; PROCEDURE Start*; BEGIN app := Excel.NewApplication(); app.PUTVisible(TRUE); app.PUTDisplayAlerts(FALSE); wb := app.Workbooks().Add(NIL); ws := Excel.This_Worksheet(wb.Worksheets().Item(CtlT.Int(1))); range := ws.Range(CtlT.Str("A1"), NIL); range.PUTValue(CtlT.Int(12345)); NEW(action); Services.DoLater(action, Services.now) END Start; PROCEDURE Stop*; BEGIN Services.RemoveAction(action); action := NIL; app.Workbooks().Close(); ws := NIL; wb := NIL; app.Quit; app := NIL; END Stop; END TestExcel. В диспетчере задач наюлюдаю как BB и Excel потихоньку отъедают память (BB съел 100 Мб и на этом не остановился). И такая картина наблюдается при чтении данных из различных объектов при использовании подсистемы Ctl. |
Автор: | Вячеслав Бойко [ Пятница, 04 Июль, 2008 18:14 ] |
Заголовок сообщения: | Re: Подсистема Ctl. |
Господа, может кто-то сможет объяснить: куда утекает память при чтении из СОМ-объекта (см. сообщение выше)? Сам не могу сообразить... |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |