Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизProgreessBar, подвисание проги Найти похожие ветки
← →
timekiller © (2010-03-12 10:39) [0]Уважаемые знатоки! У меня проблема такая:
Есть форма, на ней Progressbar (Gauge, как его назвали)...
Но толк от него пропадает, когда программа попросту занята 15минутным выполнением задачи (разбор гигабайтного XLS, например) - В заголовке появляется некое (Не отвечает), форма перекрашивается в белый цвет и всё приехали.....
Вопрос такой, для тех кто сталкивался: Как оживить Progressbar во время выполнения программы?
Алгоритм растет, что будет когда программа будет выполнятся 2 часа, допустим?....
← →
Lowlander © (2010-03-12 10:42) [1]В потоке делать нужно - тогда не будет зависания
← →
MonoLife © (2010-03-12 10:53) [2]
> Как оживить Progressbar во время выполнения программы?
Application.ProcessMessages
← →
timekiller © (2010-03-12 11:15) [3]Application.ProcessMessages(); здорово помог!
← →
Демо © (2010-03-12 17:01) [4]
> timekiller © (12.03.10 11:15) [3]
> Application.ProcessMessages(); здорово помог!
Это кажущееся улучшение.
Application.ProcessMessages нужно использовать как можно реже.
> Алгоритм растет, что будет когда программа будет выполнятся
> 2 часа, допустим?....
Толтько за счёт неаккуратного использования этого метода выполнение алгоритма может замедлиться в несколько раз.
← →
Игорь Шевченко © (2010-03-12 17:13) [5]
> Application.ProcessMessages нужно использовать как можно
> реже.
Это смелое утверждение. А почему ?
← →
Демо © (2010-03-12 17:26) [6]
> > Application.ProcessMessages нужно использовать как можно
> > реже.Это смелое утверждение. А почему ?
А зачем заставлять систему часто выполнять не нужное переключение на обработку всех поступающих приложению windows-сообщений?
Для полностью интерактивных задач это может быть и оправдано. А задача приложения, выполняющего длительный расчёт, как можно скорее закончить его. Тем более, если пользователю нужно лишь видеть эпизодически, что приложение не висит, а работает.
Если хочется достичь обеих целей - разморозить интерфейс полностью, и не прерывать расчётов, то нужно менять логику приложения.
← →
Демо © (2010-03-12 17:28) [7]При этом нужно учитывать ещё и алгоритм, во время которого выполняется Application.ProcessMessages.
Если это цикл из десятка миллионов итераций, то переключаться на каждом шаге цикла в обработку сообщений просто не имеет смысла.
← →
Игорь Шевченко © (2010-03-12 17:36) [8]Демо © (12.03.10 17:26) [6]
А я не вижу смысла менять логику приложения, если можно обойтись периодическим опросом пользовательского интерфейса.
Усложнение - не откровение.
← →
Ega23 © (2010-03-12 17:48) [9]
> Если это цикл из десятка миллионов итераций, то переключаться
> на каждом шаге цикла в обработку сообщений просто не имеет
> смысла.
На каждом - не имеет. А на каждом сотом или тысячном - вполне.
← →
KSergey © (2010-03-12 17:51) [10]> Демо © (12.03.10 17:28) [7]
> Если это цикл из десятка миллионов итераций, то переключаться
> на каждом шаге цикла в обработку сообщений просто не имеет смысла.
Это да. Но это не значит, что его нельзя использовать. А вот вызывать не каждый раз, а лишь один раз на 100 итераций расчета, например - вполне допустимо. Многопоточность на однопроцессорной машине собственно никаких улучшений относительно этого метода и не добавит.
← →
dj kondakov (2010-03-13 08:39) [11]Могу посоветовать использование потоков. Сам одно время с такой проблемой мучался, когда было нужно копировать гиговый файл с диска на диск. Перенес алгоритм копирования в поток и индикацию оттуда же сделал. Итог: файл копируется, ПрогрессБар показывает прогресс, приложение не "висит".
← →
Демо © (2010-03-13 16:27) [12]
> KSergey © (12.03.10 17:51) [10]
Application.ProcessMessages нужно использовать как можно реже <> нельзя использовать.
> Ega23 © (12.03.10 17:48) [9]
>На каждом - не имеет. А на каждом сотом или тысячном
> - вполне.
Это уже детали.
> Игорь Шевченко © (12.03.10 17:36) [8]
> А я не вижу смысла менять логику приложения, если можно
> обойтись периодическим опросом пользовательского интерфейса.
> Усложнение - не откровение.
Это и не есть откровение, а лишь предупреждение автору вопроса, чтобы не считал это единственно верным решением.
> dj kondakov (13.03.10 08:39) [11]
> Могу посоветовать использование потоков. Сам одно время
> с такой проблемой мучался, когда было нужно копировать гиговый
> файл с диска на диск. Перенес алгоритм копирования в поток
> и индикацию оттуда же сделал. Итог: файл копируется, ПрогрессБар
> показывает прогресс, приложение не "висит".
Есть разные виды задач. Например:
1. Пользователь запускает длительные расчёты. Пока расчёты выполняются, он занимается другим приложением, ждёт их окончания, чтобы начать следующий этап.
2. Пользователь запускает длительные расчёты. Пока расчёты выполняются, он в этом же приложении занимается другим делом, ожидая, пока эти расчёты закончатся, чтобы начать следующий этап.
3. Пользователь запускает длительные расчёты и идёт спать. Результаты расчёта понадобятся только на следующий день.
1. Расчёты выполняются в основном потоке. Используем Application.ProcessMessages как можно реже. (например - раз в секунду).
2. Расчёты выполняются в отдельном потоке. Нет необходимости использовать Application.ProcessMessages.
3. Расчёты выполняются в основном потоке. никаких дополнительных действий предпринимать не нужно.
← →
Anatoly Podgoretsky © (2010-03-13 16:42) [13]> Демо (13.03.2010 16:27:12) [12]
Если расчеты длительные, то ProgreessBar не очень пожзодит, лучше что то вращающая, возможно совместно с прогресс баром, для общей оченки.
← →
Ega23 © (2010-03-13 16:57) [14]
> Демо © (13.03.10 16:27) [12]
> Это уже детали.
Фигасе, "детали". Сначала мы заявляем, что
> Это кажущееся улучшение.
> Application.ProcessMessages нужно использовать как можно реже.
, а потом оказывается, что это "детали".
Слишком смело, сударь.
← →
Демо © (2010-03-13 16:57) [15]
> Anatoly Podgoretsky © (13.03.10 16:42) [13]
> > Демо (13.03.2010 16:27:12) [12]Если расчеты длительные,
> то ProgreessBar не очень пожзодит, лучше что то вращающая,
> возможно совместно с прогресс баром, для общей оченки.
Ну это если нет возможности получить точное максимальное значение для ProgressBar.
← →
Демо © (2010-03-13 16:58) [16]
> Ega23 © (13.03.10 16:57) [14]
> > Демо © (13.03.10 16:27) [12]> Это уже детали.Фигасе,
> "детали". Сначала мы заявляем, что > Это кажущееся улучшение.
> > Application.ProcessMessages нужно использовать как можно
> реже., а потом оказывается, что это "детали".Слишком смело,
> сударь.
Конечно смело. Потому что в таких простых вопросах вряд ли стоит путаться. Не так ли?
← →
Ega23 © (2010-03-13 16:59) [17]
> 2. Расчёты выполняются в отдельном потоке. Нет необходимости
> использовать Application.ProcessMessages.
За тебя этот квант система отдаёт.
← →
Ega23 © (2010-03-13 17:00) [18]
> Ну это если нет возможности получить точное максимальное
> значение для ProgressBar.
в 95% случаев - нельзя.
← →
Демо © (2010-03-13 17:04) [19]
> > 2. Расчёты выполняются в отдельном потоке. Нет необходимости
> > использовать Application.ProcessMessages.За тебя этот
> квант система отдаёт.
Но отдаёт только тогда, когда это действительно необходимо.
> Ega23 © (13.03.10 17:00) [18]
> > Ну это если нет возможности получить точное максимальное
> > значение для ProgressBar.в 95% случаев - нельзя.
Без разницы. В одном случае можно определить, в другом нельзя.
Подход разный.
← →
Игорь Шевченко © (2010-03-13 17:14) [20]
> 3. Пользователь запускает длительные расчёты и идёт спать.
> Результаты расчёта понадобятся только на следующий день.
>
Самый правильный вариант
← →
Anatoly Podgoretsky © (2010-03-13 17:25) [21]> Демо (13.03.2010 16:57:15) [15]
Возможность есть, значение известно, но количество иттераций или по другому нужное на них время настолько большое, что прогресс почти не двигается и в этом случае теряется прямое назначение. Но тут помогает двигающая полоска
← →
Демо © (2010-03-13 17:48) [22]
> Игорь Шевченко © (13.03.10 17:14) [20]
> > 3. Пользователь запускает длительные расчёты и идёт спать.
> > Результаты расчёта понадобятся только на следующий день.
> > Самый правильный вариант
Согласен. Самый быстрый ;)
> Anatoly Podgoretsky © (13.03.10 17:25) [21]
> > Демо (13.03.2010 16:57:15) [15]Возможность есть, значение
> известно, но количество иттераций или по другому нужное
> на них время настолько большое, что прогресс почти не двигается
> и в этом случае теряется прямое назначение. Но тут помогает
> двигающая полоска
Тоже верно. При очень больших значениях бегунок может менять свою позицию через большие промежутки времени. В этом случае можно даже комбинированный бегунок делать двигающаяся полоска с отображением процента выполнения...
← →
Вася (2010-03-14 10:03) [23]Application.ProcessMessages плох не тем, что якобы заметно перерасходует ресурсы процессора, а тем, что вставка в коде Application.ProcessMessages фактически равно вставке куска кода, выбранного почти случайно.
Что в ряде случаев приводит к интересным результатам. Например, имеем два метода:
procedure TMyObject.Method1;
begin
GlobalResource.Lock;
try
DoMethod1;
Application.ProcessMessages;
finally
GlobalResource.Unlock;
end
end;
procedure TMyObject.Method2;
begin
GlobalResource.Lock;
try
DoMethod2;
finally
GlobalResource.Unlock;
end
end;
В результате, если во время вызова Method1 в очереди есть сообщение, обработчик которого вызывает Method2, то Method2 попытается занять ресурс до того, как Method1 его освободил, и это при наличии одного потока.
В результате имеем программу с поистине великолепной логикой.
← →
sniknik © (2010-03-14 10:25) [24]Вася (14.03.10 10:03) [23]
а вот это уже явный логический глюк сделанный программистом... нельзя внутри блока локирования ресурсы вызывать "прерыватель", смысл локирования тогда? с тем же успехом можно "гнать" на критические секции, если вызвать внутри одной метод с попыткой занять туже секцию. (это вроде даже описано в статьях про дедлоки)
но ни критические секции ни ProcessMessages тут не виноваты, виноват программист написавший такое.
вынеси ProcessMessages за локирование и все будет в порядке.
другое дело уследить абсолютно за всем, при его использовании трудно, т.к. логика простого действия "разрывается" и что при этом разрыве произойдет (может объект "убьют" по действию пользователя) неизвестно (а предусмотреть нужно), с этим согласен.
← →
Ega23 © (2010-03-14 10:26) [25]
> В результате имеем программу с поистине великолепной логикой.
А можно ещё и объекты за собой не убивать. Чё-там, по завершении работы память всё-равно освободится...
Всё от программиста зависит. Даже Goto использовать можно.
← →
Вася (2010-03-14 11:11) [26]
> sniknik © (14.03.10 10:25) [24]
Ну так там может эта схема быть реализовано не столь явно, а более запутано - например ProcessMessages вызван где-то в глубине, внутри вызываемого отсюда метода, и тут не видно. Возможность ошибиться возрастает - речь об этом.
А возьмем другой пример: Человек нажал кнопку "долгая операция", а потом, через три минуты (процесс еще не завершен), нажал кнопку "другая долгая операция". Что получится - вторая операция начнет выполняться, а первая приостановится до окончания второй.
Врядли такая логика приемлема для большинства программ, тем более что с большой долей вероятности что-то прокосячит во время выполнения.
Я собственно к чему.
Программист, вызывающий ProcessMessages, должен закладываться на то, что вместо ProcessMessages там может внезапно оказаться что угодно, в том числе и "долгая-процедура-два", и даже "долгая-процедура-один-еще-раз".
Если бы он (программист) указал, какие именно сообщения надо отпроцессить, то он мог бы контролировать этот код, а так он его не контролирует. Я, собственно, об этом
← →
Anatoly Podgoretsky © (2010-03-14 12:09) [27]> Ega23 (14.03.2010 10:26:25) [25]
Не порть чистоту расы.
← →
Anatoly Podgoretsky © (2010-03-14 12:10) [28]> Вася (14.03.2010 11:11:26) [26]
Так это другая ошибка, программист знает что нельзя повторно нажимать кнопку, ни никакого противодействия не оказывает. У тебя какой то странный програмист, может пора его заменить более безопасным?
← →
Ega23 © (2010-03-14 12:14) [29]
> Программист, вызывающий ProcessMessages, должен закладываться
> на то, что вместо ProcessMessages там может внезапно оказаться
> что угодно, в том числе и "долгая-процедура-два", и даже
> "долгая-процедура-один-еще-раз".
В момент, когда запускается "любая долгая операция" у пользователя должна быть возможность выполнить одно единственное действие - "отмена любой долгой операции".
Если программист такую логику не реализовал - это проблема программиста.
А плодить миллион тредов для каждой операции - ну можно и так, только следить внимательно надо и потокобезопасность везде применять.
← →
Ega23 © (2010-03-14 12:14) [30]
> Не порть чистоту расы.
Не мешай троллить.... :))))
← →
Игорь Шевченко © (2010-03-14 12:32) [31]
> В момент, когда запускается "любая долгая операция" у пользователя
> должна быть возможность выполнить одно единственное действие
> - "отмена любой долгой операции".
Пользователь должен пойти спать, согласно [12]
← →
sniknik © (2010-03-14 14:05) [32]> Пользователь должен пойти спать, согласно [12]
ну а почему нет? если результат нужен только завтра.
вообще, имхо конечно, начинающие часто преувеличивают полезность многозадачных операций (именно от пользователя, типа стартовал расчет а пока идет делает что-то другое...), и вставляют их куда ни попадя, нужны они там или нет неважно. его стартуют ради результата, и если обработка действительно не сутки, а там несколько минут, то его ждут, а не переключаются на другие задачи.
ну вот например, есть такая программка MyRuLib.exe, у нее длительная обработка архивов сделана такой вот "параллельной" операцией (уж не знаю как потоком или с типа ProcessMessages) но смысла в этом чуть, т.к. первое, когда я загружаю архив, я именно этим и занимаюсь, т.е. все одно жду когда загрузится чтобы посмотреть что в нем, чего добавилось, а во вторых если работать в ней параллельно, обращаться к базе, то прога "вылетает" с ошибкой (AV вроде насколько помню), вот. т.е. чтобы архив загрузился нормально нужно ничего не трогать... (ну как раз об этом и предупреждения, трудно отследить).
ну вот, т.е. чаще всего мне и нужно ждать, и обязательно ждать иначе "глюкнет" (хотя, это уже второе дело).
и по моему было бы гораздо лучше если бы, было просто окно "идет загрузка" и блокирование всего остального. а если уж (нестандартный случай) хочется в этом момент что то старое смотреть, то не проблема запустить вторую копию программы (так не глючит, очевидно почему, процесс совсем другой). + если бы там не парились с "многозадачностью" обработка была бы немного короче (а может и намного, делая примерно тоже самое, на другой базе, но с теми же архивами я получал время в 3 раза меньше).
← →
Anatoly Podgoretsky © (2010-03-14 14:22) [33]> sniknik (14.03.2010 14:05:32) [32]
действительно в пользовательском интерфейсе пользы от многозадачности немного.
← →
Игорь Шевченко © (2010-03-14 14:25) [34]sniknik © (14.03.10 14:05) [32]
> начинающие часто преувеличивают полезность многозадачных
> операций (именно от пользователя, типа стартовал расчет
> а пока идет делает что-то другое...), и вставляют их куда
> ни попадя, нужны они там или нет неважно
Наслушаются рекомендаций и вставляют. Пользователя же хлебом не корми, дай запустить что-то длительное и не выходя из программы непременно что-то еще в ней поделать.
← →
Игорь Шевченко © (2010-03-14 14:27) [35]Я встречал (и довольно часто) использование многопоточности для запуска длительных процессов с одной целью - чтобы окно программы можно было свернуть.
← →
Anatoly Podgoretsky © (2010-03-14 14:29) [36]> Игорь Шевченко (14.03.2010 14:27:35) [35]
Я тоже иных попыток не наблюдал
← →
Игорь Шевченко © (2010-03-17 16:45) [37]Демо © (13.03.10 17:48) [22]
Кстати, любопытная дискуссия по поводу ProcessMessages:
https://forums.codegear.com/thread.jspa?messageID=218939&tstart=0
← →
Leonid Troyanovsky © (2010-03-17 18:20) [38]
> Игорь Шевченко © (17.03.10 16:45) [37]
> Кстати, любопытная дискуссия по поводу ProcessMessages:
Там (D2010) не очень интересно, видимо, глюк отладчика.
Про PM были и более содержательные обсуждения от
которых остались лишь "многие лета".
--
Regards, LVT.
← →
Демо © (2010-03-17 18:24) [39]
> Игорь Шевченко © (17.03.10 16:45) [37]
> Там (D2010) не очень интересно, видимо, глюк отладчика.
При отладке что-нибудь да не в порядке.
Особенно в конфузных ситуациях - при обработке сообщений, в многопоточных приложения, в COM.
← →
Leonid Troyanovsky © (2010-03-17 18:34) [40]
> Демо © (17.03.10 18:24) [39]
Хитро квотируешь ;)
А чего там сложного: здесь по 100 г, там соточку - так и долетели.
Уж с обработкой сообщений можно б было справиться, не бином
Ньютона, бо уж PM - в первичном потоке.
--
Regards, LVT.
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.067 c