OberonCore
https://forum.oberoncore.ru/

"Зависание" BlackBox при длительных вычислениях
https://forum.oberoncore.ru/viewtopic.php?f=1&t=130
Страница 1 из 1

Автор:  Targitay [ Вторник, 14 Март, 2006 10:52 ]
Заголовок сообщения:  "Зависание" BlackBox при длительных вычислениях

С BlackBox только начал знакомиться и запнулся на такой проблемке...

MODULE Pifagor;

IMPORT StdLog;

PROCEDURE Do*();
VAR i,j,k,m : LONGINT;
BEGIN
StdLog.String("Поехали!!!");
StdLog.Ln;
m:=15000;
FOR i:=1 TO m DO
FOR j:=(i DIV 2) TO i DO
FOR k:=1 TO j DO
IF (i*i)=((j*j)+(k*k)) THEN
StdLog.Int(i);
StdLog.String(",");
StdLog.Int(j);
StdLog.String(",");
StdLog.Int(k);
StdLog.Ln;
END;
END;
END;
END;
END Do;

END Pifagor.

При использовании Pifagor.Do BlackBox перестает реагировать на что-либо и прекращает вывод в StdLog... В Delphi это личилось вставкой вызова Application.ProcessMessages в цикл, что можно почитать на эту тему в BlackBox (исходники пытаюсь осилить, но пока не разобрался куда смотреть)...

Автор:  Илья Ермаков [ Вторник, 14 Март, 2006 11:49 ]
Заголовок сообщения: 

Здравствуйте!

Аналога ProcessMessages в BlackBox нет - не буду вдаваться в подробности, но как я понимаю, есть особенности архитектуры (в частности, принятая схема обработки TRAP'ов), из-за которых нежелательно передавать управление из пользовательской ветки выполнения в обработчик сообщений.
Ваш пример в StdLog выводит нормально - только что проверял, лог обновляется - точно также можно всегда обновлять конкретное нужное Вам отображение через вызов Views.Update. В целом же среда действительно "замораживается". Остановить выполнение любой выполняемой команды (т.е. всей цепи вызовов, начавшейся от командера, меню, кнопки...) можно, нажав Ctrl+Break.

Чтобы выполнять какие-то длительные действия параллельно, без зависания среды, используйте Services.Action - это псевдомногопоточность в ББ, они выполняются в одном потоке с GUI во время его простоя.

Автор:  Сергей Губанов [ Вторник, 14 Март, 2006 13:16 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
используйте Services.Action

Как-то так:
Код:
MODULE Pifagor;

   IMPORT L := StdLog, Services;
   
   TYPE
      Calculator = POINTER TO RECORD (Services.Action)
         index: LONGINT
      END;

   VAR
      calculator: Calculator;
      
   PROCEDURE (this: Calculator) Do;
      VAR i, j, k: LONGINT;
   BEGIN INC(this.index); i := this.index;
      FOR j := (i DIV 2) TO i DO
         FOR k := 1 TO j DO
            IF i*i = j*j + k*k THEN
               L.Int(i); L.String(","); L.Int(j); L.String(","); L.Int(k); L.Ln
            END
         END
      END;
      IF this.index < 15000 THEN
         Services.DoLater(this, Services.now)
      ELSE
         calculator := NIL;
         L.String("Готово!"); L.Ln
      END
   END Do;

   PROCEDURE Stop*;
   BEGIN
      IF calculator # NIL THEN
         Services.RemoveAction(calculator); calculator := NIL;
         L.String("Калькулятор остановлен"); L.Ln
      END
   END Stop;

   PROCEDURE Start*;
   BEGIN Stop; NEW(calculator);
      Services.DoLater(calculator, Services.Ticks() + 3 * Services.resolution);
      L.String("Калькулятор заработает через три секунды..."); L.Ln
   END Start;

END Pifagor.

Pifagor.Start - запустить фоновое вычисление,
Pifagor.Stop - остановить фоновое вычисление.

Автор:  Илья Ермаков [ Вторник, 14 Март, 2006 13:29 ]
Заголовок сообщения: 

Кстати, в HostWindows есть интересная процедура Idle - она выполняет частичную обработку сообщений. Пробовал ее - разморозки интерфейса не происходит, но кое-что меняется - например, начинает мерцать каретка. (Ни в коем случае не советую использовать в прикладном коде - модули Host не предназначены для импорта "по любому поводу").

Автор:  Targitay [ Вторник, 14 Март, 2006 13:37 ]
Заголовок сообщения: 

Спасибо...

Автор:  Halega [ Среда, 26 Апрель, 2006 15:14 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
Здравствуйте!

Ваш пример в StdLog выводит нормально - только что проверял, лог обновляется - точно также можно всегда обновлять конкретное нужное Вам отображение через вызов Views.Update. В целом же среда действительно "замораживается". Остановить выполнение любой выполняемой команды (т.е. всей цепи вызовов, начавшейся от командера, меню, кнопки...) можно, нажав Ctrl+Break.


А если во время вычислений переключиться на другое окно (например, включить "Диспетчер задач"), то BlackBox виснет намертво, и уже не спасает Ctrl-Break. Приходится снимать задачу. :-(

Автор:  Halega [ Среда, 26 Апрель, 2006 15:20 ]
Заголовок сообщения: 

Я также попался на том, что забыл инициализировать переменную:
Код:
MODULE HalegaHello0;
   IMPORT StdLog;
   
   PROCEDURE Do*;
      VAR x: INTEGER;
   BEGIN
      WHILE x # 5 DO
         StdLog.String("Hello World"); StdLog.Ln;
         x := x + 1
      END
   END Do;
END HalegaHello0.


Запустил программу и у названия окна BlackBox появилась надпись "(не отвечает)". Решил посмотреть, что же будет дальше, но когда BlackBox отъел 450 Мб оперативки, моё терпение кончилось, я снял задачу. А компилятор CP не предупреждает об использовании неинициализированной переменной?

Автор:  GlSal [ Среда, 26 Апрель, 2006 19:18 ]
Заголовок сообщения: 

Команда меню "Info"/"Analyze Module" - анализ модуля - находит эту ошибку - "used before set"

Автор:  Grabli [ Пятница, 28 Апрель, 2006 08:12 ]
Заголовок сообщения: 

А вот если в функцию WinApi передать адресс на адресс, будет ещё веселее.

С огромной скоростью вылезет куча окошечек с ошибкой, BB сожрет все ресурсы компа, и иногда помочь может только RESET.

Автор:  Илья Ермаков [ Пятница, 28 Апрель, 2006 12:02 ]
Заголовок сообщения: 

Не обидитесь, если поправлю? "Адрес" пишется по-русски с одной С. Это в английском - address.

Автор:  Grabli [ Пятница, 28 Апрель, 2006 12:16 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
Не обидитесь, если поправлю? "Адрес" пишется по-русски с одной С. Это в английском - address.


Не обижусь. Мне это многие говорят. Привычка.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/