![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
что-то типа ShowModal, но иначе :) [D7, Win95/98, WinME, NT4, Win2k, WinXP]
dUM © (2005-06-24 17:24:00)Пока в программе выполняются какие-то действия, пользователю нужно показать какое-нибуть окошко с прогресс баром, или просто с надписью вроде "ожидайте". Я делаю примерно вот так:
form1.Enabled:=false;
form2.show;
.....
.....
form2.close;
form2.Enabled:=true;
Но данный вариант мне очень не по душе. Подскажите, если ли альтернативы? Грубо говоря нужно чтобы во время отображения form2, у пользователя небыло доступа ни к каким функциям form1. Ну что-то типа SHowModal, только чтобы ещё и мой код паралельно выполнялся)
Юрий Зотов (2005-06-27 14:45:00) [1]> TUser © (27.06.05 10:13) [29]
Да просто компонент, который можно легко бросить на форму и настроить в ИО. Вызываем его метод Execute, тот создает поток, настраивает его по свойствам компонента и запускает. Код потока реализуется пользователем в обработчике события компонента.
Просто удобная форма работы с потоками, ничего больше. Ну и, возможно, избегаем некоторого дублирования кода в ряде случаев.
TUser (2005-06-27 10:13:00) [2]> В то же время, стоит лишь написать простейшую компонентскую оболочку вокруг TThread - и задачка решается универсально, без проблем, раз и навсегда.
Что имеется ввиду под 'оберткой'? Введение дополнительной функции принудительного завершения потока через TerminateThread?
evvcom (2005-06-27 09:35:00) [3]
> Отвечаем и расхлебываем КОНЕЧНО МЫ! Но как порой это сложно!
Что касается баз данных, то выбор базы определяется в основном пожеланиями заказчика. Если в его пожеланиях локальные базы, то мы можем постараться убедить его в ненадежности, неудобности и пр. их использования. Серверные же боле-менее работают нормально. Поэтому чаще всего, если что-то работает не так, как следовало бы, то это действительно уже наши огрехи. Имхо. :)
Германн (2005-06-27 02:13:00) [4]2 Юрий Зотов © (26.06.05 11:03) [20]
>> Германн © (26.06.05 03:07) [19]
>> "Select" - это из баз данных? Если так, то причем тут мы
>> все? Ну да, они там что-то делают, а мы тут расхлебываем.
>Кто отвечает перед конечным юзером за качество программы - ее >разработчик, или разработчик используемой ею СУБД? Вот причем >тут мы. Приходится расхлебывать, никуда не денешься.
Отвечаем и расхлебываем КОНЕЧНО МЫ!Но как порой это сложно!
Иногда я рад, что единственная моя "продажная" программа была изначально сделана на Д1 под W3.11! (Т.е. IDAPI и Paradox). Тут хоть RxLib что-то имеет. :)
Eraser (2005-06-26 16:43:00) [5]lookin © (26.06.05 16:40) [25]
Термин "атомарная" вообще обозначает операцию, которая выполняется одной командой процессора, но в данном контексте - это операция, которую нельзя прервать с пом. ProcessMessages, типа SQL запроса или копирования файла.
lookin (2005-06-26 16:40:00) [6][24] Юрий Зотов © (26.06.05 15:17)
Погодите, может неправильно понял термин "атомарная операция"? Я под ней разумею некий набор действий, который выполняется один раз. У меня длительность такого выполнения, скажем, 0,5 секунды. Теперь в цикле я выполняю этот набор действий, скажем, 1000 раз. Тогда длительность всего выполнения будет 500 секунд, и вот как раз между двумя соседними атомарными операциями я использую Application.ProcessMessages
Юрий Зотов (2005-06-26 15:17:00) [7]> lookin © (26.06.05 12:36) [23]
> Только если она длительная.
Так о них и речь. Если нет длительных операций, то нет и вообще никаких проблем.
lookin (2005-06-26 12:36:00) [8][22] Юрий Зотов © (26.06.05 12:15)
>>Пока не завершится длительная атомарная операция
Только если она длительная. В моем случае длительность такой атомарной операции составляет не более полусекунды.
Юрий Зотов (2005-06-26 12:15:00) [9]> lookin © (26.06.05 11:33) [21]
> Через Processmessages...
См. [14], [15] и [17]. Пока не завершится длительная атомарная операция, никакой ProcessMessages не поможет. Поскольку сработает только после ее завершения. Заставка Delphi - тому пример.
lookin (2005-06-26 11:33:00) [10][20] Юрий Зотов © (26.06.05 11:03)
Это верно, мне самому не очень нравится, что окно программы нерисовабельно во время длительных операций... Я потоки не использую. Однако при выполнении действия прогресс-бар у меня адекватно отображает ход процесса, и содержимое модального окна тоже перерисовывается. Через Processmessages... Другое дело, что главное окно уже не перерисовывается...
Юрий Зотов (2005-06-26 11:03:00) [11]> lookin © (26.06.05 03:01) [18]
> Зачем в отдельном потоке?
См. [10]-[14]. Вот иллюстрирующий пример. Запустите любую оконную программу (хотя бы справку) и сдвиньте ее окно к краю экрана. Теперь запустите Delphi - появится заставка. "Повозите" окном справки по окну заставки и обратите внимание, как фигово эта заставка перерисовывается.
Происходит это потому, что обработка сообщений окна-заставки и собственно загрузка Delphi выполняются в одном потоке. И, хотя окно заставки периодически принудительно перерисовывается, происходит это недостаточно часто - потому что пока выполняется какой-то кусок кода загрузки, перерисовать заставку нет возможности. Вот и получаем фиговую перерисовку.
Бросьте на форму кнопку, а в ее обработчике напишите длительный цикл, на пару минут. Пусть он даже ничего не делает, а просто имитирует какую-то длительную операцию. Запустите программу, нажмите кнопку и пока выполняется этот цикл, тоже "повозите" по окну своей программы любым другим окном. Нравится Вам такаяпрограмма? Мне - нет.
ОК, теперь меняем схему. Выносим тот же самый длительный цикл в отдельный поток, а кнопка теперь пусть запускает не сам цикл, а этот поток. Повторяем эксперимент с перекрытием окон и получаем совершенно другую картину. Вот такаяпрограмма мне уже нравится. А Вам?
Перерисовка - это только наглядный пример, а вообще сказанное относится к обработке любыхсообщений. Пока поток занят выполнением какого-то кода, он не имеет возможности обработать ни одно сообщение - поэтому окна этого потока не могут перерисоваться, юзер не может ничего с ними сделать, все контролы на всех окнах не работают и пр. Но стоит только вынести тот же самый код в отдельный поток, как все сразу становится ОК.
> Германн © (26.06.05 03:07) [19]
> "Select" - это из баз данных? Если так, то причем тут мы
> все? Ну да, они там что-то делают, а мы тут расхлебываем.
Ктоотвечает перед конечным юзером за качество программы - ееразработчик, или разработчик используемой ею СУБД? Вот причем тут мы. Приходится расхлебывать, никуда не денешься.
> Пока что вижу только одну причину использовать отдельную
> нить - мат. вычисления.
Мат. вычисления, обработка файлов, вообще любая длительная операция с любыми данными. Даже просто StringReplace с очень длинным текстом.
Германн (2005-06-26 03:07:00) [12]2 Юрий Зотов © (26.06.05 02:55) [17]
Юр, только не пинай меня сразу! :)
"Select" - это из баз данных? Если так, то причем тут мы все? Ну да, они там что-то делают, а мы тут расхлебываем. :(
Пока что вижу только одну причину использовать отдельную нить - мат. вычисления.
lookin (2005-06-26 03:01:00) [13]>>Показываете форму с прогрессбаром модально, а код выполняете в
>>отдельном потоке
Зачем в отдельном потоке?
Юрий Зотов (2005-06-26 02:55:00) [14]> jack128 © (25.06.05 18:53) [15]
> лудше вообще не допускать подобных операций..
Лудше-то, оно, конечно, лудше... да вот только не всегда возможно. Какой-нить шибко хитрый Select для заполнения контролов формы - простейший пример.
В то же время, стоит лишь написать простейшую компонентскую оболочку вокруг TThread - и задачка решается универсально, без проблем, раз и навсегда.
dUM (2005-06-25 23:06:00) [15]В моей проге есть операции как на несколько секунд, но отображение окна необходимо, так и на несколько десятков минут. Но они не атомарные, потоки я не создаю, а окна перерисовываются по processmessages. Уж не знаю тонкостей - хорошо это или плохо, но работает! :)
jack128 (2005-06-25 18:53:00) [16]Юрий Зотов © (25.06.05 18:02) [14]
Есть атомарная(т.е. неразрывная, внутрь которой не влезешь) достаточно длительная операция.
Ну в этом случае, конечно никак. Только в поток эту процедуру пихать..
НО 1) Такие операции (ИМХО) достаточно редко на практике встречаются
2) Пихание в поток - это тоже в сомнительное удовольствие, так как коли операция АТОМАРНА , то ты не сможешь завершить её когда те этого хочется.. Ну кроме TerminateThread, но этот вариант не стит рассматривать.. Это все к тому, что лудше вообще не допускать подобных операций..
Юрий Зотов (2005-06-25 18:02:00) [17]> Eraser © (25.06.05 17:35) [13]
> processmessages вставить.
Есть атомарная (т.е. неразрывная, внутрь которой не влезешь) достаточно длительная операция. Куда вставлять ProcessMessages?
Некуда...
:-(
Eraser (2005-06-25 17:35:00) [18]Юрий Зотов © (25.06.05 17:31) [12]
Ну, хотя бы только одной нормальной перерисовки формы?
Ну это можно есть processmessages вставить. Хотя конечно с потоками более универсальное решение.
Если задача на пол часа, даже на 5 минут - однозначна потоки.
Юрий Зотов (2005-06-25 17:31:00) [19]> Defunct © (25.06.05 17:25) [11]
> А если поток полчаса выполняться надумал?
То форма спокойно продолжает получать и обрабатывать сообщения. Она нормально перерисовывается, можно сделать кнопки "пауза" и/или "прервать" - и т.п.
Как без второго потока добиться того же? Ну, хотя бы только одной нормальной перерисовки формы?
<off>
Спасибо!
</off>
Defunct (2005-06-25 17:25:00) [20]> Юрий Зотов
Ну и пусть себе выполняется. А если поток полчаса выполняться надумал?
<off>
С прошедшим!
Желаю Вам всего того, что Вы сами себе пожелаете ;>
</off>