Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];

Вниз

Работа с потоками в Delphi с использованием VCL   Найти похожие ветки 

 
YuRock   (2004-01-15 14:18) [0]

Уважаемые мастера!
Как вы знаете, в Delphi Help"е четко написано: "methods that access a VCL object and update a form must only be called from within the main VCL thread" - т.е. обращаться к объктам VCL (т.е. окнам и т.д.) можно только в главном потоке.
Я же, решив проверить это утверждение, получил следующий результат: на самом деле с объектами работать можно, но как только идет обращени к непосредственно оконному свойству - поток зависает...
Происходит это потому, что зависает ф-ция SendMessage, которая отправляет соответствующее сообщение окну.

Так как мне необходимо было обойти эту проблему, я нашел 2 выхода:
1. Отправлять сообщение окну через PostMessage, а по этому сообщению выполнять какие нужно операции с окном. Этот метод будет работать в главном потоке - по-этому все в порядке.
2. Отказаться от использования VCL. В файле проекта убрать инициализацию Application и цикл обработки сообщений написать вручную:

while GetMessage(msg, 0, 0, 0) do begin
TranslateMessage(msg);
DispatchMessage(msg);
end;


Оба этих метода каждый по-своему плохи. Так как и VCL я люблю, и SendMessage из другого потока иногда необходимо выполнять.

Вопрос: почему (конкретно) не получается выполнить SendMessage и как (если возможно) эту проблему обойти?


 
Polevi   (2004-01-15 14:20) [1]

TThread.Synchronize


 
Digitman   (2004-01-15 14:23) [2]


> Происходит это потому, что зависает ф-ция SendMessage, которая
> отправляет соответствующее сообщение окну.


а ты выяснил конкретные причины "зависания", прежде чем делать какие-то умозаключения ?


 
YuRock   (2004-01-15 14:31) [3]

> Polevi © (15.01.04 14:20) [1]
> TThread.Synchronize

Это не выход (я даже писать об этом не стал). Какой смысл делать поток, если написать в нем Synchronize? Нет, иногда можно, но чаще всего прийдется все операции туда засовывать, а это идиотизм, извините.

> Digitman © (15.01.04 14:23) [2]
> а ты выяснил конкретные причины "зависания", прежде чем делать какие-то умозаключения ?

Вот об этих "конкретных" причинах я и хотел у Вас (и не только у Вас) спросить, т.к. виснет любой SendMessage!


 
Digitman   (2004-01-15 14:41) [4]


> Это не выход (я даже писать об этом не стал). Какой смысл
> делать поток, если написать в нем Synchronize?


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


> виснет любой SendMessage


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


 
YuRock   (2004-01-15 14:54) [5]

> Digitman © (15.01.04 14:41) [4]
> смысл как раз прямой : если требуется синхронизация некоего вызова метода с осн.код.потоком

Да, но не ради любого же SendMessage Synchronize вызывать?!! Это же тормоз страшный!

> Digitman © (15.01.04 14:41) [4]
> очевидно, потому что поток-приемник сообщения в этот момент занят некоей длительной операцией

Нет. Дело не в этом. Если б причины были в этом, я б вопрос не задавал. Если хотите - можете сами попробовать. Если Application.Run не использовать - ничего не зависает. Вот где-то там и проблема, но в чем конкретно?..


 
Digitman   (2004-01-15 15:01) [6]


> Да, но не ради любого же SendMessage Synchronize вызывать?!!
> Это же тормоз страшный!


Synchronize() предназначен для иного, хотя и использует в своей реализации Sendmessage()

А "тормоза" - это, скорей всего, признак неумелого или неуместного использования метода

приводи сюда код. посмотрим, что там к чему у тебя ... может, ты просто с параметрами наблудил что-то ...


 
YuRock   (2004-01-15 15:44) [7]

> приводи сюда код. посмотрим, что там к чему у тебя

И глубоко извиняюсь, но, к сожалению, я сейчас не могу повторить этой ситуации. Как только смогу - немедленно приведу код.


 
Digitman   (2004-01-15 15:50) [8]


> YuRock © (15.01.04 15:44) [7]


как вам будет угодно, сударь)

думаю, это прежде всего - в Ваших интересах


 
panov   (2004-01-15 16:28) [9]

>YuRock © (15.01.04 14:18)
"methods that access a VCL object and update a form must only be called from within the main VCL thread"

либо использовать различные методы синхронизации при работе различных потоков, например, критические секции -

TCriticalSection - VCL

InitializeCriticalSection/EnterCriticalSection/LeaveCriticalSection/DeleteCriticalSection


 
YuRock   (2004-01-15 16:30) [10]

Уважаемые мастера! Я повторил ситуацию, но уже сам понял, в чем была проблема (во мне :))).

Дело в том, что в главном потоке стоял WaitForSingleObject, который ждал, пока мой поток даст сигнал (SetEvent).
Т.е. главный поток временно висел, а мой поток повис, пока главный не обработает SendMessage, но так как он тоже висит - ...

В общем, всем спасибо. С вопросом разобрался (благодаря Digitman - при попытке повторить ситуацию и показать пример кода).


 
YuRock   (2004-01-15 16:47) [11]

Так что продолжаем любить VCL!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.008 c
1-93564
Xmen
2004-01-17 10:56
2004.01.29
Ввод данных


1-93510
Filatov
2004-01-18 18:34
2004.01.29
Как программно узнать путь к папке Windows


7-93713
Tik
2003-11-13 16:17
2004.01.29
Буфер .


1-93449
den74
2004-01-19 11:05
2004.01.29
Печать DBChart


1-93518
Pantera111
2004-01-18 17:12
2004.01.29
Запуск моей программы через





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский