OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 12 Ноябрь, 2019 06:11

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
 Заголовок сообщения: Подсистема Ctl.
СообщениеДобавлено: Пятница, 29 Июнь, 2007 15:54 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Вот такая проблема. Создаем новое приложение (сервер автоматизации). Выполняем обработку данных. После сборщик мусора должно все подобрать, а сервер по идее выгрузиться. Однако, он выгружаться и не думает. Попробуйте просто эти строки - потыкал по коммандеру - и получил кучу процессов Excel.
Код:
   IMPORT   CtlExcel := CtlExcel9;

   PROCEDURE ...
   VAR
      excel: CtlExcel.Application;
   BEGIN
      excel := CtlExcel.NewApplication();
      ...
У кого есть какие идеи? Проблема в ББ реализации COM/Ctl?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подсистема Ctl.
СообщениеДобавлено: Пятница, 29 Июнь, 2007 17:30 

Зарегистрирован: Понедельник, 05 Июнь, 2006 09:49
Сообщения: 327
Откуда: Ленинград, Емельянов Алексей Николаевич
А Вы после обработки сделали excel.quit?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Понедельник, 02 Июль, 2007 11:41 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Угу. Даже excel.Quit; excel := NIL; Kernel.Collect....
Если сделать окно ёкзеля видимым, то Quit видимость убирает, а процесс остается. Может в ББ что-то его держит. Вот только что?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Против лома нет приема
СообщениеДобавлено: Понедельник, 02 Июль, 2007 11:46 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Пока выкручиваюсь прибиванием процесса:
Код:
   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;

Надо только юзерам сообщать, что во время работы екзелем пользоваться запрещается :lol:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Понедельник, 02 Июль, 2007 19:36 
Аватара пользователя

Зарегистрирован: Воскресенье, 04 Декабрь, 2005 16:15
Сообщения: 15
Откуда: Украина, Мариуполь
Евгений Темиргалеев писал(а):
Угу. Даже 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 
Аватара пользователя

Зарегистрирован: Воскресенье, 04 Декабрь, 2005 16:15
Сообщения: 15
Откуда: Украина, Мариуполь
Мда, попробовал переложить выше-написанное в 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 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
У меня 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 
Аватара пользователя

Зарегистрирован: Воскресенье, 04 Декабрь, 2005 16:15
Сообщения: 15
Откуда: Украина, Мариуполь
Евгений Темиргалеев писал(а):
У меня 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, либо убивать процессы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подсистема Ctl.
СообщениеДобавлено: Суббота, 14 Июнь, 2008 12:16 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 12:00
Сообщения: 79
Откуда: Россия, Санкт-Петербург
В меню "COM" есть пункт "Collect", который вызывает процедуру HostMenus.Collect, которая и прибивает Excel.
Код:
VAR
  app: CtlExcel.Application;
  .....

   PROCEDURE Exit*;
   BEGIN
      app:= NIL;
      HostMenus.Collect;
   END Exit;



Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подсистема Ctl.
СообщениеДобавлено: Среда, 18 Июнь, 2008 11:05 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 12:00
Сообщения: 79
Откуда: Россия, Санкт-Петербург
Куда утекает память?
Код:
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.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Подсистема Ctl.
СообщениеДобавлено: Пятница, 04 Июль, 2008 18:14 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 12:00
Сообщения: 79
Откуда: Россия, Санкт-Петербург
:?:
Господа, может кто-то сможет объяснить: куда утекает память при чтении из СОМ-объекта (см. сообщение выше)?
Сам не могу сообразить...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB