Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 843

Раздел: Delphi » Прочее
/ вопрос открыт /

Здравствуйте, эксперты!
Ответьте, пожалуйста на следующий вопрос. Если я в отдельном потоке (TThread) создаю экземпляр некотрого объекта MyObj, образованного от TControl, то в каком потоке будет происходить обработка сообщений, получаемых MyObj и вообще "жизнь" объекта MyObj, в том, в котором он создан или в основном потоке приложения?

Мережников Андрей Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Мережников Андрей (статус: Абитуриент)
Вопрос отправлен: 9 августа 2007, 17:46
Состояние вопроса: открыт, ответов: 3.

Ответ #1. Отвечает эксперт: Feniks

Здравствуйте, Мережников Андрей!
Так как из потока нельзя получать напрямую доступ к другим объектам приложения, и на оборот, к объектам потока из основного приложения, значит и Ваш объект будет "жить" в пределах своего родителя, т.е. потока.

Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 9 августа 2007, 17:51
Оценка за ответ: 3

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

Ответ #2. Отвечает эксперт: Вадим К

Здравствуйте, Мережников Андрей!
Мало кто создал объект. Надо знать кто его родитель. Объект может быть создан внутри потока, а работать с ним может основной поток.
Вообще то, так как вы создаёте визуальный компонент, то у него должно быть окно, которое и будет пересылать сообщения. у потока окна нет, поэтому он (поток) не сможет пересылать сообщения компоненту.
Если же вы при создании попытаетесь вызвать с потока как MyComponent:=TMyComponent.Create(Form1), то тут может работать, а может и глючить.

В последней рассылке была моя статья о том, как качать файл с интернета в дополнительном потоке. Там используется компонент TIdHTTP. при создании в качестве родителя я передавал ему nil, но он не требует сообщений. Все Event\'s его через специальные переходники взаимодействуют с основным потоком, но они работают в дополнительном потоке.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 9 августа 2007, 18:00
Оценка за ответ: 4

Комментарий к оценке: У потока действительно нет окна, но он может и посылать сообщения (PostMessage,SendMessage,Perform), так и получать их (PeekMessage). А родитель создаваемого компонента nil. Так как он будет обрабатывать получаемые сообщения?

Ответ #3. Отвечает эксперт: DNK

Здравствуйте, Мережников Андрей!
В TThread идет только исполнение кода метода execute. Обработка сообщений осуществляется методом Application.Run, который запускается в основном потоке.

Ответ отправил: DNK (статус: Студент)
Время отправки: 9 августа 2007, 22:42
Оценка за ответ: 3

Комментарий к оценке: А если сообщение послано непосредственно потоку PostThreadMessage и перехватывается в потоке PeekMessage, то где идет обработка сообщения?

Мини-форум вопроса

Всего сообщений: 13; последнее сообщение — 13 августа 2007, 23:10; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 10 августа 2007, 11:16 [#1]:

Для начала, скажие какой компонент хотите использовать и какую функциональность надо.

Цитата:


У потока действительно нет окна, но он может и посылать сообщения (PostMessage,SendMessage,Perform), так и получать их (PeekMessage). А родитель создаваемого компонента nil. Так как он будет обрабатывать получаемые сообщения?

Нет, надо ещё код, который будет ему пересылать сообщения.
Галочка "подтверждения прочтения" - вселенское зло.
DNK

DNK (статус: Студент), 10 августа 2007, 12:59 [#2]:

Уважаемый Мережников Андрей.
Если вам надо организовать обработку сообщений в дополнительном потоке, надо было сразу это указать в вопросе.
Мое мнение, решение возлагать одновременно задачи на создание и управление компонентами на один класс ошибочным. Проект будет закрепощенным. Гораздо более правильным будет инкапсулировать поток в компонент.
"Digital Networked Knight"
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 12 августа 2007, 20:55 [#3]:

Здравствуйте, уважаемые эксперты! Спасибо за интерес к данной теме.
по порядку на ваши вопросы: мне не нужен визуальный компонент, класс TControl выбран в качестве родительского только потому, что он способен воспринимать сообщения. Сообщения посылаются с помощью Perform (SendMessage и PostMessage в этом случае не срабатывает, потому,что объект не содержит окна,способного принять такие сообщения).
Выделение в отдельный поток необходимо потому, что необходима система в реальном времени отслеживающая состояние COM-порта и посылающая туда команды в зависимости от пришедшей информации. При этом еще необходимо периодически сбрасывать данные в БД. В принципе это наибольший тормоз, может быть его и надо выделить в отдельный поток. Хотя еще надо и с пользователем тоже общаться почти в реальном времени. Извините за такую запутанность вопроса. Юыло бы проще, решил бы сам.
Вадим К

Вадим К (статус: Академик), 13 августа 2007, 11:20 [#4]:

не знаю, зачем вам нужно в потоке обрабатывать сообщения. Я писал подобную систему, где нужно было в потоке работать с с устройством через ком порт. мало того, таких устройств у меня было до 8 штук.
И с пользователем система общалась - она OpenGl прорисовывает состояния датчиков, которые по портам опрашивались. Учитывая что датчиков на одном порту могло быть до сотни штук, никаких проблем небыло.

Вы нашли интересное решение и решили его применить. но скорее всего оно здесь не применимо.
Наверно вам нужно перепроектировать структуру предложения.

С потока отсылать в основное приложение сообщения - это нормально, но назад - это ужас.
Сформулируйте точнее задачу.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 13 августа 2007, 14:51 [#5]:

Здравствуйте. Я тоже пришел к выводу, что систему надо перпроектировать - чем проще, тем надежней :-)
Почему передача сообщений в поток - ужас? Я,пока, не нашел другого способа, чтобы передать данные в работающий поток. Можно, конечно через глобальные переменные, но кто с уверенностью скажет, какую строку кода выполняет поток,когда пытаешься извне изменить в нем переменные? Я использую для этого PostThreadMessage. Подскажите где найти хорошую инфу по потокам.
Вадим К

Вадим К (статус: Академик), 13 августа 2007, 14:58 [#6]:

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

Мережников Андрей (статус: Абитуриент), 13 августа 2007, 17:02 [#7]:

Про критические секции не только читал, но и разбирал их "по косточкам" :-) Как и все остальные объекты в SyncObjs. Критическая секция заставляет вызывающий поток ждать, пока освободиться, а при отправке сообщения посылающий объект ставит сообщение в очередь и выполняется дальше :-)
Конечно если не использовать SendMessage, которая ждет обработки сообщения.
Вадим К

Вадим К (статус: Академик), 13 августа 2007, 17:12 [#8]:

А кто заставляет в критической секции век сидеть? зашёл, флаг поставил и свалил. А поток в цикле крутиться и флажки проверяет. опс, флажок, сделаем то и то.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 13 августа 2007, 17:21 [#9]:

Тем мне и нравится программирование, что одну задачу можно решить несколькими способами :-) И чем глубже вникаешь в язык, тем больше вариантов. Согласитесь, что сообщения и критические секции в данном случае применяются одинаково. Что в случае секций, что в случае сообщений, отправляемых в поток, нужен цикл, проверяющий либо флажки, либо наличие сообщений (PeekMessage).
Вадим К

Вадим К (статус: Академик), 13 августа 2007, 17:28 [#10]:

согласен, методы подобны друг-другу, но
цикл обычно в потока уже есть, это раз.
А во вторых, почитайте о паттернах программирования. там вы обнаружете, что это уже паттерн такой есть.
К прочтению рекомендованна книга "банды четырёх" (так и гуглить). Хотя там примеры и на Си, но ничего не изменяет.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 13 августа 2007, 17:39 [#11]:

Спасибо за ссылку :-)
PekkMessage тоже проверяется в цикле. Отдельного цикла не образуется. Эта функция не ждет прихода сообщения, а лишь проверяет его наличие :-)
Так что разницы нет - писать if Flag... или if PeekMessage()...
Может быть порекомендуете еще литературу по Delphi. Кроме Архангельского, Фленова ("Библия Delphi","Delphi глазами хакера"), Суворова ("Справочник Delphi. Базовые классы"), Корнякова ("Delphi+MS Office"),Фаронова ("Система программирования Delphi"),Тома Свана ("Секреты 32-разрядного программирования в Delphi") которые у меня есть

А по поводу дискуссии о преимуществах сообщений и критических секций - думаю развивать ее - мало смысла
Вадим К

Вадим К (статус: Академик), 13 августа 2007, 18:01 [#12]:

Архангельского я рекомендую юзать только как справочник по функциям, но не более.
К хорошим книгам по делфи отнесу Марко Кэнту и Ксавье (Хавьер) Пачеко
Галочка "подтверждения прочтения" - вселенское зло.
DNK

DNK (статус: Студент), 13 августа 2007, 23:10 [#13]:

Примелькалась на глаза следующая статья про использование потоков (http://www.interface.ru/home.asp?artId=6105). Мне кажется для вашей затеи наиболее подходящим будет использование события с автосбросом (последний пример в статье).
"Digital Networked Knight"

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:36
Выполнено за 0.03 сек.