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

Вниз

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

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

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

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

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


 
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;


 
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 - и все будет ясно.


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

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


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


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

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


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

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


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


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

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


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

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


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

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


 
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;


 
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:13) [6]

Sorry, Synchronize.


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

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

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

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


 
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, а получать его ой как неприятно.


 
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: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]
Наконец и я понял, о чем вы говорите.
Спасибо.


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

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


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


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

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

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

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

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


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


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

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

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

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

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


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

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

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

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


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

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

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

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


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

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


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

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


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

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

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

if GetCurrentThreadId = mainThreadId then .. else ..

или

if GetCurrentThreadId = SomeThreadId then .. else ..


 
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 из главного (или еще какого).


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

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



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

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

Наверх





Память: 0.53 MB
Время: 0.044 c
1-1082651430
Canpek
2004-04-22 20:30
2004.05.09
Запрос совета


1-1082561531
Morfey
2004-04-21 19:32
2004.05.09
Маленький шрифт на канаве


3-1081941984
Flashas
2004-04-14 15:26
2004.05.09
S DBgrid..


4-1079308855
kothor
2004-03-15 03:00
2004.05.09
Есть вопрос по меню.


3-1081458389
Igoryok
2004-04-09 01:06
2004.05.09
Как вызвать функцию из Access





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