Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

что-то типа ShowModal, но иначе :) [D7, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2

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>


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо