Главная страница
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-1082415396
VPV
2004-04-20 02:56
2004.04.11
Minimize+Maximize и alClient


14-1081956844
}|{yk
2004-04-14 19:34
2004.04.11
Первичный ключ - ошибка создания


3-1078997841
RavenD
2004-03-11 12:37
2004.04.11
почему теряются данные при запросе?


3-1079020318
Дмитрий 2004
2004-03-11 18:51
2004.04.11
Распечатка нескольких значений строк в DBGrid


14-1082048518
RealRascal
2004-04-15 21:01
2004.04.11
Экономия траффика