Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.07 c
2-1270722524
Учащийся
2010-04-08 14:28
2010.08.27
перевести Integer в Char, String в Char


2-1271079259
noob_one
2010-04-12 17:34
2010.08.27
Можно ли в delphi2007 объявить функцию в одном файле (модуле)


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


15-1273436998
Юрий
2010-05-10 00:29
2010.08.27
С днем рождения ! 10 мая 2010 понедельник


2-1269429471
@!!ex
2010-03-24 14:17
2010.08.27
AV при выделении памяти





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский