Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программа выполняет длительный процесс, и находится в статусе "не отвечает" 
:(
    Опции темы
Нитонисе
Дата 22.9.2012, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Программа долго выполняет вычисления. Время может исчисляться минутами. При этом во время вычисления она как бы зависает. Хотя в конце концов вычисления заканчиваются и программа возвращается в штатный режим. Мне хотелось бы реализовать в окне главной формы индикатор процесса, который бы постепенно заполнялся, при этом бы давалась текстовая информация что программа делает в данную секунду. В свзяи с этим появились два вопроса:
1. Время вычисления в общем случае неизвестно и не ясно как можно охарактеризовать объем вычислений. Отсюда возникает вопрос - а из каких соображений определять текущий процент выполнения работы? Как это делается обычно, когда общий объем неизвестен? 
2. Хотелось бы рядом с прогресс-баром иметь кнопку Отмена, чтобы можно было остановить вычисления в любой момент. Но как я уже выше отметил - программа "зависает" при работе и на команды не реагирует. Так как все же в этом случае можно реализовать подобную функцию?
PM MAIL   Вверх
DarkProg
Дата 22.9.2012, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: нет
Всего: 19



Цитата(Нитонисе @  22.9.2012,  14:10 Найти цитируемый пост)
1. Время вычисления в общем случае неизвестно и не ясно как можно охарактеризовать объем вычислений. Отсюда возникает вопрос - а из каких соображений определять текущий процент выполнения работы? Как это делается обычно, когда общий объем неизвестен? 

Ну можно сделать как у майкрософта, когда осталось 5 секунд, которые длятся вечность  smile 
А вообще я в таком случае просто вывожу окошко, где написано что-то вроде "Жвите, я тут считаю..." и обычно просто плавно менются последовательно 1, 2, 3 точки и по новой.

Если вы делаете только вычисления и хотите чтобы программа реагировала, то можно вычисления засунуть во второй поток и если что, то по кнопке отмена остановить поток и вырубить программу.
Можно использовать очень много ProcessMessages в процессе вычислений, но это не решение проблемы IMHO.


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
artsb
Дата 22.9.2012, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Во-первых, нужно всю работу вынести в отдельный поток. тогда и окно не будет зависать и кнопка будет работать, и прогрессбар будет отрисовываться, и работу можно будет всегда прервать.
Во-вторых, если продолжительность операции не известна, то можно сделать прогрессбар в стиле бегающих квадратиков (есть такое свойство у прогрессбара). Начиная с Vista, отображаются не квадратики, а свечение. Ну или разобраться с выполняемой работой, и всё таки. как-нибудь рассчитать время работы. Что за работа то?


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Нитонисе
Дата 22.9.2012, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(artsb @  22.9.2012,  13:39 Найти цитируемый пост)
Во-первых, нужно всю работу вынести в отдельный поток.

Никогда такого не делал. Можно элементарный пример?

Цитата(artsb @  22.9.2012,  13:39 Найти цитируемый пост)
Во-вторых, если продолжительность операции не известна, то можно сделать прогрессбар в стиле бегающих квадратиков

Просто показывать, что программа считает - наверное не очень удобно. Хотелось бы, чтобы отображалась текущая позиция расчета. Суть вычислений - расчет строительной конструкции. Алгоритм весьма ветвистый. Какие-то блоки считаются, какие-то нет. Все зависит от исходных данных. Некоторые блоки могут очень долго считаться, но при других исходных эти же блоки считаются быстро. То есть в одном случае какой-то блок может занять 90% расчетного времени, а вдругом случае - всего 10%. Похоже что в таких условиях прогрессбар с отображение текущего выполнения не лучшая идея? Возможно стоит разбить весь расчет на некоторые структурные части и просто каким либо образом (текстовым или графическим) информировать пользователя в каком блоке сейчас идет вычисление.
PM MAIL   Вверх
artsb
Дата 22.9.2012, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Нитонисе @  22.9.2012,  16:05 Найти цитируемый пост)
Никогда такого не делал. Можно элементарный пример?

Копайте в сторону TThread. Добавить в проект поток можно через меню:
1. File -> New -> Other...
2. C++Builder Projects -> C++Builder Files
3. Thread Object

А дальше изучайте справку и ищите примеры в интернете, т.к. в двух словах описать не получится.

Цитата(Нитонисе @  22.9.2012,  16:05 Найти цитируемый пост)
Просто показывать, что программа считает - наверное не очень удобно.

Да. Но бывает, что выхода нет.

Цитата(Нитонисе @  22.9.2012,  16:05 Найти цитируемый пост)
Возможно стоит разбить весь расчет на некоторые структурные части и просто каким либо образом (текстовым или графическим) информировать пользователя в каком блоке сейчас идет вычисление. 

Тоже идея.
Можно ещё разбить всю вашу работу на этапы. Например, если у вас получилось 23 этапа, то вы так и выставляйте в Progressbar'е: Min = 0, Max = 23. И потом, после каждого этапа делайте Position++


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Dem_max
Дата 22.9.2012, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39





--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Нитонисе
Дата 22.9.2012, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Спасибо, буду разбираться.
PM MAIL   Вверх
Нитонисе
Дата 23.9.2012, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Создал класс, производный от TThread - TMyThread.
Добавил в него функцию DoCalculate(){Form1->Calculate).
В методе Execute прописал всего одну строчку - Synchronize(DoCalculate).

В основной программе в обработчике клика на кнопку, запускающую расчет, написал такой код.
Код

Thread = new TMyThread(false); // Thread - член класса Form1
Thread->FreeOnTerminate = true;


В результате сам расчет-то выполняется, но основная форма программы все также недоступна во время его выполнения. То есть например отменить выполнение расчета возможности нет. Почему так?
PM MAIL   Вверх
Dem_max
Дата 23.9.2012, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



Да не может быть такого, ты явно что то не то делаешь, но мы не телепаты. Но могу предположить что ты в DoCalculate делаешь длительный расчет, который опять же выполняется в главном потоке окна что и было до этого, вопрос почему конкретно не выполняешь расчет в самом потоке ??


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
artsb
Дата 23.9.2012, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Dem_max, правильно говорит. Этим вызовом:
Код

DoCalculate(){Form1->Calculate)

вы запускаете на выполнение расчёты. Причём, запускаете работу с синхронизацией с VCL. Вот всё и виснет. Если в методе Calculate() нет работы с VCL, то можете из потока просто вызвать 
Код

Form1->Calculate

без синхронизации. Тогда всё должно быть нормально. Если же в этом методе есть обращение к VCL, то переносите весь код в поток, НО синхронизировать нужно ТОЛЬКО работу с VCL. Иначе, опять всё повиснет.

Это сообщение отредактировал(а) artsb - 23.9.2012, 21:29


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Dem_max
Дата 24.9.2012, 02:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



ТС я же тебе ссылку давал там разжован материал для самых тупых.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Riviero
Дата 24.9.2012, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 25.3.2010

Репутация: 2
Всего: 3



Код

    Application->ProcessMessages();


Это сообщение отредактировал(а) Riviero - 24.9.2012, 09:38
PM MAIL   Вверх
Нитонисе
Дата 24.9.2012, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(artsb @  23.9.2012,  21:28 Найти цитируемый пост)
Если же в этом методе есть обращение к VCL, то переносите весь код в поток, НО синхронизировать нужно ТОЛЬКО работу с VCL.

Перенести весь код в поток - это ж надо менять области видимости переменных. А что значит "НО синхронизировать нужно ТОЛЬКО работу с VCL"? Вот класс TForm - это класс VCL? Если у меня расчетом непосредственно занимается другой класс TCalculate, являющийся членом класса TForm, значит ли это, что обращение к методам TCalculate я работаю с VCL?
PM MAIL   Вверх
artsb
Дата 24.9.2012, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Нитонисе @  24.9.2012,  10:35 Найти цитируемый пост)
Если у меня расчетом непосредственно занимается другой класс TCalculate, являющийся членом класса TForm, значит ли это, что обращение к методам TCalculate я работаю с VCL? 

Нет, если ваш класс не потомок какого-нибудь VCL-класса.

Цитата(Нитонисе @  24.9.2012,  10:35 Найти цитируемый пост)
А что значит "НО синхронизировать нужно ТОЛЬКО работу с VCL"?

Например,
Код

// расчёты
// расчёты
// расчёты
// расчёты
Form1->Label1->Caption = myResult1;
// расчёты
// расчёты
// расчёты
// расчёты

Вот обращение к свойствам или методам VCL-класса, это и есть то, что я подразумевал под работой с VCL. Т.е. в данном случае, это изменение свойства Caption для Label1. Вот эту операцию и нужно синхронизировать.

Добавлено через 1 минуту и 15 секунд
Цитата(Нитонисе @  24.9.2012,  10:35 Найти цитируемый пост)
Перенести весь код в поток - это ж надо менять области видимости переменных.

Конечно. Придётся как-то приспосабливаться. А, вообще, это нужно было заранее продумывать. Тогда и переделывать ничего бы не пришлось.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
DarkProg
Дата 24.9.2012, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: нет
Всего: 19



Цитата(Нитонисе @  24.9.2012,  11:35 Найти цитируемый пост)
Если у меня расчетом непосредственно занимается другой класс TCalculate

Ну и зашибись, если всё вынесено в отдельный класс. Просто запихайте класс в поток, там его создайте, выполните все расчёты, а результат верните в форму используя синхронизацию.

Цитата(Нитонисе @  24.9.2012,  11:35 Найти цитируемый пост)
Перенести весь код в поток - это ж надо менять области видимости переменных.

Ну если используете глобальные переменные, то я вам не завидую. В остальном просто надо подумать где и что надо передать. Самый просто способ это передать копии всех необходимых значений в поток, чтобы меньше надо было делать синхронизаций.


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0725 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.