Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.05 c
10-1167226388
Priest
2006-12-27 16:33
2010.08.27
Собственная реализация IDispatch


2-1274516991
ali
2010-05-22 12:29
2010.08.27
Проблема с переходом на D2010


15-1266239343
Den
2010-02-15 16:09
2010.08.27
Узнать количество обращений к серверу


15-1274560189
Юрий
2010-05-23 00:29
2010.08.27
С днем рождения ! 23 мая 2010 воскресенье


15-1266787803
Юрий
2010-02-22 00:30
2010.08.27
С днем рождения ! 22 февраля 2010 понедельник