На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> Thread в Delphi , Создал поток, пустил в нем форму
    Создал поток, пустил в нем форму. Не могу добиться реагирования на действия до окончания работы запущенного потока. Как этого избежать?
      что значит
      Цитата
      yyy, 31.05.04, 16:12
      пустил в нем форму

      ?
        Цитата Song @ 31.05.04, 17:18
        что значит
        Цитата
        yyy, 31.05.04, 16:12
        пустил в нем форму

        ?

        Cоздаю поток, который в свою очередь создает форму, при создании которой идет подключение к БД и считывание информации путем серии SQL запросов. Так вот, до окончания создания формы приложение не реагирует на действия пользователя. Иными словами, созданная нить потоказахватывает все на себя. А мне нужно, что бы пока создается форма, пользователь мог работать с другими пунктами приложения.
          Вообще чтобы обращаться к методам VCL из потока надо использовать Synchronize()
          Но с формой такое не прокатит т.к. форме нужно обрабатываеть сообщения. Или она у тебя просто для декоративных вещей (отображение хода вычислений, прогресса и т.д.) ?
            А зачем форму создавать в потоке? Создавай ее просто так, а потом уже их потока можешь ее изменять :)
              Цитата
              p_kolya, 1.06.04, 12:48
              А зачем форму создавать в потоке? Создавай ее просто так, а потом уже их потока можешь ее изменять

              Неа, без Synchronize изменять форму из потока все равно не получится :'(
                Цитата Петрович,1.06.04, 19:00
                Цитата
                p_kolya, 1.06.04, 12:48
                А зачем форму создавать в потоке? Создавай ее просто так, а потом уже их потока можешь ее изменять

                Неа, без Synchronize изменять форму из потока все равно не получится :'(

                Теперь создаю поток. Внутри потока создаю компоненты ADO, или просто запускаю какой нибудь цикл.
                Это все реализую в виде процедуры, которая перекрывает метод Execute. Вызывается естественно через Synchronize(). Вызывается поток из формы по нажатию какой либо расположенной на ней кнопке. Но возникает следующая проблема: пока не отработает нить вызванного потока, компоненты этой формы, а так же созданных ранее созданных форм не реагируют на действия пользователя.

                {Cоздаю поток, который в свою очередь создает форму, при создании которой идет подключение к БД и считывание информации путем серии SQL запросов. Так вот, до окончания создания формы приложение не реагирует на действия пользователя. Иными словами, созданная нить потоказахватывает все на себя. А мне нужно, что бы пока создается форма, пользователь мог работать с другими пунктами приложения. }
                  Перечитай ещё раз моё сообщение.
                    Цитата
                    Guest, 2.06.04, 15:17
                    Теперь создаю поток. Внутри потока создаю компоненты ADO, или просто запускаю какой нибудь цикл.
                    Это все реализую в виде процедуры, которая перекрывает метод Execute. Вызывается естественно через Synchronize(). ....

                    Через Synchronize() надо делать только короткие действия, обычно исзменение свойств визуальных компонентов.
                    Дело в том, что метод вызываемый посредством Synchronize() выполняется в контексте основного потока приложения. Это как раз и обеспечивает возможность использования нереентерабельных VCL-компонент.
                    Для лучшего понимания поясню как работает Synchronize().
                    При вызове Synchronize(), вызвавший поток посылает собщение в специально созданную оконную процедуру. Причем посылает его с помощью SendMessage, т.е. синхронно. Следовательно, пославший его поток приостанавливается до завершения обработки сообщения оконной процедурой. Та самая, специально созданная оконная процедура всегда создается в контексте основного потока приложения. По правилам Windows, оконная процедура всегда вызывается в контексте зарегестрировавшего ее потока. Следовательно, в нашем случае, сообщение "дойдет" до оконной процедуры только тогда, когда основной поток "пойдет" в Windows за очередным сообщением. Как только это случится, в контексте основного потока будет вызвана эта специальная оконная процедура, ну и из нее, тот метод который дали на вход Synchronize(). Естественно, пока из него не произойдет возврат, никакие другие действия, основной поток совершать не может.
                    Ну вот, хотел как проще, но наверное только запутал.

                    Короче, надо знать следующее:
                    1. На время выполнения Synchronize() вызвавший поток приостанавливается;
                    2. Если основной поток чем-то занят, например вызвал Sleep(5000) в OnClick кнопки, то метод вызванный из любого другого потока посредством Synchronize() не начнет выполняться пока основной поток не закончит выполнения OnClick.
                    3. Пока не закончит выполняться метод вызванный посредством Synchronize(), основной поток никаких других действий не выполняет. Соответственно, не будет и реакции на ЛЮБЫЕ внешние события (клавиатура, мышь, таймеры, прорисовка, и пр.).

                    Отсюда выводы:
                    - В отдельный поток имеет смысл выделять действия не требующие частого обращения к визуальным компонентам VCL. Лучше если их вообще нет :).
                    - Все обращения к свойствам и методам визуальных компонент VCL, например обновление свойства Progress компонента tProgressbar или Caption какого нибудь tLabel'а, можно делать только из метода вызываемого через Synchronize().
                    - Все действия выполняемые в методе вызываемом через Synchronize() должны занимать как можно меньше времени.
                    - Не стоит очень часто вызывать Synchronize(). Иначе, у Вас будет теряться очень много времени на переключение потоков.

                    В принципе, есть еще и другие способы обращения к VCL из потоков, но это уже другая история. Итак уже целая статья получилась, да простят меня модераторы.
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0392 ]   [ 16 queries used ]   [ Generated: 27.04.24, 13:20 GMT ]