![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Окно - прогресс в отдельном потоке [D7, WinXP]
Дмитрий Белькевич © (2008-07-17 19:28:00)Нужно реализовать простую прогресс-форму с прогресс баром, небольшой картинкой и кнопкой прерывания процесса.
Нужно, что бы она работала в отдельном потоке.
То, что обычные формы работать в потоке не будут, знаю.
То что рекомендуют выносить код в поток знаю. Но не представляется возможным - прогресс применяется где-то в 25-30 местах и делать 30 разных потоков нецелесообразно.
Переделываю с обычной формы, так как применение processmessages не всегда допустимо, и при долгом процессе часто бывает, что форма прогресса не реагирует на вызов 'hide', оставаясь 'висеть'.
Может быть кто-то видел готовое решение, скорее всего, как я понял, на API. Несколько часов гугленья не принесли результата.
Сергей М. (2008-07-18 14:20:00) [21]
> Как можно обработать нажатие кнопки на форме - прогрессе,
> и её передвижение, не 'прокручивая' всю очередь?
А причем здесь Application.ProcessMessages ?
Использование оного по твоемуже условию невозможно - окно с прогресс-баром должно быть создано в контексте дополнительногопотока...
Игорь Шевченко (2008-07-18 14:11:00) [22]Дмитрий Белькевич © (18.07.08 13:51) [33]
Насколько я понимаю, основной поток (который выполняет некую работу) будет оповещать поток с формой отображения каким-то образом о собственно прогрессе (например, вызывая PostThreadMessage) или передавая потоку адрес переменной, где находится значение прогресса, а поток с окном, скажем, по таймеру, будет читать эту переменную и отображать прогресс. Это понятно.
А вот как основной поток узнает, что ему надо остановить длинный режим ?
Дмитрий Белькевич (2008-07-18 13:51:00) [23]
> У меня к автору вопрос - каким образом будет определяться,
> что на форме с прогрессом нажата кнопка "Остановить" ?
В [26]:
В окне будет флаг - отменено. Основной поток будет периодически его проверять. Изначально, при открытии окна флаг сбрасывается, юзер нажал кнопку - флаг устанавливается. Собственно, оно у меня и сейчас так же с формой работает.
Дмитрий Белькевич (2008-07-18 13:49:00) [24]>Вызов этого метода - не единственный и не лучший способ реакции на сообщения.
Как можно обработать нажатие кнопки на форме - прогрессе, и её передвижение, не 'прокручивая' всю очередь?
>Ну если ты изобретатель собственной терминологии
Хорошо, пусть это будет отвелчение общего потока. Оно мне, думаю, не критично.
Игорь Шевченко (2008-07-18 13:39:00) [25]У меня к автору вопрос - каким образом будет определяться, что на форме с прогрессом нажата кнопка "Остановить" ?
Сергей М. (2008-07-18 13:19:00) [26]
> Отвлечение - это выполнение очереди событий основным потоком
> с помощью ProcessMessages
Вызов этого метода - не единственный и не лучший способ реакции на сообщения.
> По терминологии. Это не следует считать 'отвлечением'
Ну если ты изобретатель собственной терминологии, то продолжай в том же духе, караванщик)
Дмитрий Белькевич (2008-07-18 11:23:00) [27]
> Основной поток будет периодически его проверять.
По терминологии. Это не следует считать 'отвлечением'. Отвлечение - это выполнение очереди событий основным потоком с помощью ProcessMessages. В моём случае.
Дмитрий Белькевич (2008-07-18 11:23:00) [28]
> ну-ну
Собака лает, караван идёт (с) народная мудрость.
Dennis I. Komarov (2008-07-18 11:19:00) [29]> делать буду именно так.
ну тогда делай как решил, и не грузи мозг.
Потом переделывать больше придется...
Дмитрий Белькевич (2008-07-18 11:19:00) [30]В окне будет флаг - отменено. Основной поток будет периодически его проверять. Изначально, при открытии окна флаг сбрасывается, юзер нажал кнопку - флаг устанавливается. Собственно, оно у меня и сейчас так же с формой работает.
Dennis I. Komarov (2008-07-18 11:18:00) [31]> Весь код уже написан, и достаточно хорошо работают.
ну-ну
Сергей М. (2008-07-18 11:11:00) [32]
> юзер должен по логике работы приложений либо обязательно
> дождаться конца какой-то продолжительной его части, либо
> нажать кнопку 'отмена'
Если основной поток занят и не реагирует ("не отвлекается") ни на какие сигналы, то каим образом ты собираешься просигнализировать ему о нажатии юзером кнопки "Отмена", даже если события этой кнопки ты успешно обработаешь в окне того самого доп.потока, о котором ты завел речь ?
Дмитрий Белькевич (2008-07-18 11:03:00) [33]
> Перенести прогресс с формы на StatusBar,
Думал. Тоже проблема - кнопка 'Остановить' бывает нужна.
> Алгоритм, который "не должен ни на что отвлекаться", следует
> реализовать в дополнительном, а не основном потоке.
Я не спорю.
Часть тяжеловесной по времени логики уже вынесено в потоки, к потокам написаны соответствующие обёртки для определения их состояния, готовности, остановки, повтора действия итд.
Но часть логики выносить в потоки не было смысла, так как юзер должен по логике работы приложений либо обязательно дождаться конца какой-то продолжительной его части, либо нажать кнопку 'отмена'.
Весь код уже написан, и достаточно хорошо работают. За исключением некоторых случаев. Сейчас стоит задача переделать окно - прогресс с минимальным изменением проектов. Согласитесь, что сделать одно окно проще, чем 30 разных потоков. Сейчас, правда, начнут обвинять, что больше на форуме сижу, чем делаю ;). Но. Я уже всё решил, делать буду именно так.
Сергей М. (2008-07-18 08:25:00) [34]
> Дмитрий Белькевич © (18.07.08 02:32) [16]
Все с ног на голову поставлено)
Алгоритм, который "не должен ни на что отвлекаться", следует реализовать в дополнительном, а не основном потоке.
Задача же основного потока в VCL-приложении (да и не только в VCL) - интерфейс взаимодействия с пользователем: обеспечение своевременной реакции на события пользовательского ввода/вывода.
Т.е. "тяжелая" бизнес-логика выносится в доп.поток[и], тем самым основной поток освобождается от несвойственной ему работы. Его работа, как, например, в твоем случае - отрисовка прогресс-бара и прочих контролов, ожидание и элементарная обработка клавиатурных и мышиных событий, координация взаимодействия доп.потоков и т.п.
ЮЮ (2008-07-18 06:28:00) [35]Перенести прогресс с формы на StatusBar, который перерисовывается и без processmessages, достаточно StatusBar.Repaint там, где был Application.Processmessages.
Дмитрий Белькевич (2008-07-18 03:25:00) [36]>1. уволить архитектора.
Не представляется возможным ;)
>так и навоять тогда отдельный поток и окошко на чистом API к нему, в чем проблемы то, примеров полно в сети )
О! Читай первый пост ;) Мне нужен пример. В чистом API - не силён, к сожалению. Надеюсь на готовое прогресс-окно. Хорошо, хоть [9] нашел. Пока только это.
Eraser (2008-07-18 03:06:00) [37]> [18] Дмитрий Белькевич © (18.07.08 02:56)
1. уволить архитектора.
2.
> Сделать одну форму (для любителей придираться к терминам
> - окно) в отдельном потоке - проше в 30 раз.
так и навоять тогда отдельный поток и окошко на чистом API к нему, в чем проблемы то, примеров полно в сети )
Дмитрий Белькевич (2008-07-18 02:56:00) [38]Объяснение выше. Сейчас имеется такая форма. Была надежда, что она будет работать хорошо. Однако, как показала практика, она работает с проблемами.
Форма уже использована где-то в тридцати местах разных программ. И сейчас писать 30 разных тредов - просто нереально, так как там и работа с VCL, и с базой, и с пересылкой данных по сети, много всякого, это потребует большой лишней обвязки.
А с проблемой что-то делать нужно.
Сделать одну форму (для любителей придираться к терминам - окно) в отдельном потоке - проше в 30 раз.
Eraser (2008-07-18 02:44:00) [39]> [16] Дмитрий Белькевич © (18.07.08 02:32)
> что бы в основном потоке, где происходят различные продолжительные
> действия
вообще то для различных продолжительных действий и придумали доп. потоки. а так все перевернуто с ног на голову и под это еще велосипед изобретается.
Дмитрий Белькевич (2008-07-18 02:32:00) [40]Объясню.
Доппоток нужен, что бы в основном потоке, где происходят различные продолжительные действия, не вызывать ProcessMessages.
Так как из-за этого иногда происходят некоторые неприятные спецеффекты.
То есть, что бы сообщения обрабатывал только дополнительный поток, а основной - работал бы не отвлекаясь на обработку сообщений, пока не закончатся эти самые продолжительные действия.
Но главное - даже не это. Иногда форма не прячется Hid'ом. То есть, я показываю форму, делаю некоторые действия, форма обновляется ProcessMessages'ом, в конце я делаю 'Hide', и - ничего. Форма отсаётся 'висеть' над приложением, не реагируя на кнопку 'закрыть'. Приложение приходится убивать.
Если со спецэффектами (читай - глюками) я еще как-то могу повоевать, то против отсутствия реакции на 'Hide' я бессилен. В некоторых местах приложения пришлось вообще убрать прогресс-форму, так как она там висла почти в 100% случаев.