![]() |
|
|
![]()
|
|
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Программа долго выполняет вычисления. Время может исчисляться минутами. При этом во время вычисления она как бы зависает. Хотя в конце концов вычисления заканчиваются и программа возвращается в штатный режим. Мне хотелось бы реализовать в окне главной формы индикатор процесса, который бы постепенно заполнялся, при этом бы давалась текстовая информация что программа делает в данную секунду. В свзяи с этим появились два вопроса:
1. Время вычисления в общем случае неизвестно и не ясно как можно охарактеризовать объем вычислений. Отсюда возникает вопрос - а из каких соображений определять текущий процент выполнения работы? Как это делается обычно, когда общий объем неизвестен? 2. Хотелось бы рядом с прогресс-баром иметь кнопку Отмена, чтобы можно было остановить вычисления в любой момент. Но как я уже выше отметил - программа "зависает" при работе и на команды не реагирует. Так как все же в этом случае можно реализовать подобную функцию? |
|||
|
||||
| DarkProg |
|
|||
![]() Законченный романтик ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1784 Регистрация: 11.3.2009 Где: Земля Репутация: нет Всего: 19 |
Ну можно сделать как у майкрософта, когда осталось 5 секунд, которые длятся вечность А вообще я в таком случае просто вывожу окошко, где написано что-то вроде "Жвите, я тут считаю..." и обычно просто плавно менются последовательно 1, 2, 3 точки и по новой. Если вы делаете только вычисления и хотите чтобы программа реагировала, то можно вычисления засунуть во второй поток и если что, то по кнопке отмена остановить поток и вырубить программу. Можно использовать очень много ProcessMessages в процессе вычислений, но это не решение проблемы IMHO. -------------------- "И твоя голова всегда в ответе за то куда сядет твой зад..." "Я студент - скажите с какого я ВУЗа..." |
|||
|
||||
| artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Во-первых, нужно всю работу вынести в отдельный поток. тогда и окно не будет зависать и кнопка будет работать, и прогрессбар будет отрисовываться, и работу можно будет всегда прервать.
Во-вторых, если продолжительность операции не известна, то можно сделать прогрессбар в стиле бегающих квадратиков (есть такое свойство у прогрессбара). Начиная с Vista, отображаются не квадратики, а свечение. Ну или разобраться с выполняемой работой, и всё таки. как-нибудь рассчитать время работы. Что за работа то? -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Никогда такого не делал. Можно элементарный пример?
Просто показывать, что программа считает - наверное не очень удобно. Хотелось бы, чтобы отображалась текущая позиция расчета. Суть вычислений - расчет строительной конструкции. Алгоритм весьма ветвистый. Какие-то блоки считаются, какие-то нет. Все зависит от исходных данных. Некоторые блоки могут очень долго считаться, но при других исходных эти же блоки считаются быстро. То есть в одном случае какой-то блок может занять 90% расчетного времени, а вдругом случае - всего 10%. Похоже что в таких условиях прогрессбар с отображение текущего выполнения не лучшая идея? Возможно стоит разбить весь расчет на некоторые структурные части и просто каким либо образом (текстовым или графическим) информировать пользователя в каком блоке сейчас идет вычисление. |
|||
|
||||
| artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Копайте в сторону TThread. Добавить в проект поток можно через меню: 1. File -> New -> Other... 2. C++Builder Projects -> C++Builder Files 3. Thread Object А дальше изучайте справку и ищите примеры в интернете, т.к. в двух словах описать не получится.
Да. Но бывает, что выхода нет. Тоже идея. Можно ещё разбить всю вашу работу на этапы. Например, если у вас получилось 23 этапа, то вы так и выставляйте в Progressbar'е: Min = 0, Max = 23. И потом, после каждого этапа делайте Position++ -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 14 Всего: 39 |
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Спасибо, буду разбираться.
|
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Создал класс, производный от TThread - TMyThread.
Добавил в него функцию DoCalculate(){Form1->Calculate). В методе Execute прописал всего одну строчку - Synchronize(DoCalculate). В основной программе в обработчике клика на кнопку, запускающую расчет, написал такой код.
В результате сам расчет-то выполняется, но основная форма программы все также недоступна во время его выполнения. То есть например отменить выполнение расчета возможности нет. Почему так? |
|||
|
||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 14 Всего: 39 |
Да не может быть такого, ты явно что то не то делаешь, но мы не телепаты. Но могу предположить что ты в DoCalculate делаешь длительный расчет, который опять же выполняется в главном потоке окна что и было до этого, вопрос почему конкретно не выполняешь расчет в самом потоке ??
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| artsb |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Dem_max, правильно говорит. Этим вызовом:
вы запускаете на выполнение расчёты. Причём, запускаете работу с синхронизацией с VCL. Вот всё и виснет. Если в методе Calculate() нет работы с VCL, то можете из потока просто вызвать
без синхронизации. Тогда всё должно быть нормально. Если же в этом методе есть обращение к VCL, то переносите весь код в поток, НО синхронизировать нужно ТОЛЬКО работу с VCL. Иначе, опять всё повиснет. Это сообщение отредактировал(а) artsb - 23.9.2012, 21:29 -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
||||
|
|||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 14 Всего: 39 |
ТС я же тебе ссылку давал там разжован материал для самых тупых.
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| Riviero |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 136 Регистрация: 25.3.2010 Репутация: 2 Всего: 3 |
Это сообщение отредактировал(а) Riviero - 24.9.2012, 09:38 |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Перенести весь код в поток - это ж надо менять области видимости переменных. А что значит "НО синхронизировать нужно ТОЛЬКО работу с VCL"? Вот класс TForm - это класс VCL? Если у меня расчетом непосредственно занимается другой класс TCalculate, являющийся членом класса TForm, значит ли это, что обращение к методам TCalculate я работаю с VCL? |
|||
|
||||
| artsb |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 39 Всего: 64 |
Нет, если ваш класс не потомок какого-нибудь VCL-класса. Например,
Вот обращение к свойствам или методам VCL-класса, это и есть то, что я подразумевал под работой с VCL. Т.е. в данном случае, это изменение свойства Caption для Label1. Вот эту операцию и нужно синхронизировать. Добавлено через 1 минуту и 15 секунд
Конечно. Придётся как-то приспосабливаться. А, вообще, это нужно было заранее продумывать. Тогда и переделывать ничего бы не пришлось. -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
||||
|
|||||
| DarkProg |
|
||||
![]() Законченный романтик ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1784 Регистрация: 11.3.2009 Где: Земля Репутация: нет Всего: 19 |
Ну и зашибись, если всё вынесено в отдельный класс. Просто запихайте класс в поток, там его создайте, выполните все расчёты, а результат верните в форму используя синхронизацию.
Ну если используете глобальные переменные, то я вам не завидую. В остальном просто надо подумать где и что надо передать. Самый просто способ это передать копии всех необходимых значений в поток, чтобы меньше надо было делать синхронизаций. -------------------- "И твоя голова всегда в ответе за то куда сядет твой зад..." "Я студент - скажите с какого я ВУЗа..." |
||||
|
|||||
![]()
|
| Правила форума "С++ Builder" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C++ Builder | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |