Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

Класс с событиями в отдельном потоке   Найти похожие ветки 

 
mRodion ©   (2004-04-23 15:01) [0]

Добрый день, господа.
Сразу прошу сильно не раздражаться, поскольку с тредами ни разу не работал, но читал про них уже некоторые статьи (в том числе, и на этом замечательном сайте).

А вопрос у меня такой: можно ли класс, унаследованный от TThread, снабдить событиями как обычные VCL компоненты, которые привязать в основном потоке, а вызывать в этом Thread"е?

Задача просто в том, чтобы переписать уже существующую компоненту таким образом, чтобы она работала в отдельном потоке. Пока не совсем представляю, как это сделать. Может ссылочки какие-нибудь посоветуете?


 
VMcL ©   (2004-04-23 15:10) [1]

>>mRodion ©  (23.04.04 15:01)

...
if Assigned(FSomethingDone)
 Synchonize(DoSomethingDone);
...

procedure TMyThread.DoSomethingDone;
begin
  FSomethingDone(...);
end;


 
evvcom ©   (2004-04-23 15:10) [2]

Можно. Обработчик события, который будет выполняться в основном потоке, надо и вызывать уже из основного потока. Посмотрите, как реализован вызов события OnTerminate - и все будет ясно.


 
Тимохов ©   (2004-04-23 15:10) [3]


> которые привязать в основном потоке

К чему привязать?
К методам формы например?
Или как?
Что будут эти события делать?


> Задача просто в том, чтобы переписать уже существующую компоненту
> таким образом, чтобы она работала в отдельном потоке

Визуальную/невизуальную?
Зачем?


 
Smithson ©   (2004-04-23 15:12) [4]

Компонента обраюатывает ввод пользователя и/или осуществляет вывод. По идеологии VCL все это делает только основной поток приложения. Обойти это возможно, только зачем? Расскажи подробнее про задачу, наверняка есть решение попроще.


 
evvcom ©   (2004-04-23 15:12) [5]


> procedure TMyThread.DoSomethingDone;
> begin
   if Assigned(FSomethingDone) then // Это здесь должно быть обязательно!!!
>     FSomethingDone(...);
> end;


 
VMcL ©   (2004-04-23 15:13) [6]

Sorry, Synchronize.


 
VMcL ©   (2004-04-23 15:14) [7]

>>evvcom ©  (23.04.04 15:12) [5]

>Это здесь должно быть обязательно!!!

Ты код в [1] внимательно читал?


 
evvcom ©   (2004-04-23 15:32) [8]


> Ты код в [1] внимательно читал?

Достаточно внимательно. Дело в том что в [1]
 if Assigned(FSomethingDone)
   Synchonize(DoSomethingDone);
выполняется в дополнительном потоке. Пока очередь дойдет до DoSomethingDone в основном потоке может произойти нечто типа
 FSomethingDone := nil;
и тогда мы получаем AV, а получать его ой как неприятно.


 
mRodion ©   (2004-04-23 15:39) [9]

>VMcL ©   (23.04.04 15:10) [1]
Все настолько просто?

>Smithson ©   (23.04.04 15:12) [4]
Подробнее? Пожалуйста.

Есть многодокументное приложение, в каждом дочернем окне которого используется компонент для работы с сокетами (основан на TidTCPClient). Не смотря на то, что idAnteeFreeze создан, все равно не получается добиться одновременного приема больших файлов во всех дочерних окнах. Сначала принимается файл в одном окне, потом в другом, а третье может успеть отвалиться по таймауту.

Хотелось бы переделать ту самую компоненту работы с сокетами, чтобы она была в отдельном потоке, а результат своей работы (она сейчас вызывает событие FOnRecieceImage, в котором и передает принятую картинку) она бы выдавала прежним способом, чтобы не переделывать код в дочерних окнах.


 
mRodion ©   (2004-04-23 15:43) [10]

> evvcom ©   (23.04.04 15:32) [8]
Наконец и я понял, о чем вы говорите.
Спасибо.


 
Тимохов ©   (2004-04-23 15:45) [11]


>  что idAnteeFreeze создан, все равно не получается добиться
> одновременного приема больших файлов во всех дочерних окнах

а и не получится - vcl принципиально однопотоковая.

просто так событие (то биш метод формы) из потока не вызвать, нужно делать через synchronize.

В общем-то выше это уже сказали.

В чем проблемы остались?


 
mRodion ©   (2004-04-23 15:52) [12]

Осталось только понять, можно ли из основного потока вызывать методы отдельного потока :)

Поскольку в текущей реализации сокетного объекта есть несколько методов и свойств по управлению. Например, сокетному объекту передавалась величина таймаута ожидания данных и ряд других. Кроме того, есть несколько методов, которые осуществляют запрос  серверной стороне на получение данных.

Это возможно?


 
Smithson ©   (2004-04-23 15:54) [13]

Методы - можно, только исполняться они будут в основном потоке :)
А что бы они работали в отдельном потоке, надо как то указать другому потоку, что он должен что-то сделать. Например, послать сообщение. Или флаг выставить.


 
Digitman ©   (2004-04-23 16:02) [14]

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

если тек.поток (т.е. поток, в котором исполняется данный метод-обработчик) неизвестен, то ничто не мешает в методе обработчике выполнить проверку :

if GetCurrentThreadId = mainThreadId then .. else ..

или

if GetCurrentThreadId = SomeThreadId then .. else ..


 
evvcom ©   (2004-04-23 16:11) [15]

Код, выполняемый в доп.потоке, реализуется в методе Execute. Как только Execute закончился - считай, что всё, нет твоего потока. Более не запустишь. Т.е. в Execute делают, например, цикл с анализом какого-то флага. Для этого специально предусмотрено свойство Terminated. Когда нечего потоку делать, делаешь Suspend там же в Execute. Появилась для него работа - Resume из главного (или еще какого).



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

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.029 c
1-1082741990
Lena19
2004-04-23 21:39
2004.04.11
checkbox1.Font.Color:=clred; а в ответ тишина


7-1080035858
Sheng
2004-03-23 12:57
2004.04.11
Всё тот-же COM-порт


3-1078892257
garry79
2004-03-10 07:17
2004.04.11
Почему IBExpert не может показать некоторые данные в базе?


14-1082365331
АлексейК
2004-04-19 13:02
2004.04.11
Вот и верь теперь своим глазам.


4-1079599813
b0bi
2004-03-18 11:50
2004.04.11
Как получить Handle